C++ 按基类对象访问派生类资源时出错
我有一个基类叫做base,还有一个基类的派生类叫做derived, 基类指针可以指向派生类对象,也可以访问其资源,但我在执行相同操作时遇到错误C++ 按基类对象访问派生类资源时出错,c++,pointers,inheritance,derived-class,base-class,C++,Pointers,Inheritance,Derived Class,Base Class,我有一个基类叫做base,还有一个基类的派生类叫做derived, 基类指针可以指向派生类对象,也可以访问其资源,但我在执行相同操作时遇到错误 class Base { public: int a; }; class Derived : public Base { public: float b; void DoSomething() { cout<<"Derived"; } }; int main() { Bas
class Base
{
public:
int a;
};
class Derived : public Base
{
public:
float b;
void DoSomething()
{
cout<<"Derived";
}
};
int main()
{
Base * pBase = new Derived();
pBase->DoSomething();
pBase->a = 5;
pBase->b = 0.2f;
return 0;
}
如果它太基础,请原谅,我是c++的初学者是的,您可以使用
Base
指针指向派生的
类,尽管如此,Base
指针必须知道方法,以便选择最适合调用的方法,如果Base
指针不知道这些变量和函数的存在,则无法调用它们
:
输出:
派生
编辑:
正如您在注释部分中所建议的,转换派生类在这种特定情况下会起作用,但它通常会显示设计糟糕的代码,正如所指出的,还请注意,这有一些原因说明为什么这不是最好的主意
正如我所说,如果必须这样做,请使用dynamic\u cast()
请注意,在任何情况下,您仍然需要虚拟析构函数来正确实现多态性
虚拟析构函数
通过指向基类的指针删除对象会调用未定义的行为,除非基类中的析构函数是虚拟的
这还不是全部,请检查。如果您使用
派生的作为基础
,它受基础
所知的限制Base
没有DoSomething
因此Base
不能使用DoSomething
。但请参见此Base*pBase=new-Derived()代码>我们可以这样做。我已经研究过这是允许的,即基类指针可以存储对其派生类的引用derived
base
。它知道Base
知道的一切,并且可以用作Base
。但是Base
无法知道派生的知道什么。Base*
可能指向一个派生的
,也可能指向一个派生的
,它具有不同的功能。如果您希望在Base
中的行为可以由Base
派生的类指定。经过一点研究,我发现我正在寻找静态caststatic_cast(pBase)->DoSomething()代码>如果你可以编辑你的答案,解释相同的问题,我可以接受这个问题的答案。你还可以提一下这样做有什么坏处吗way@FarhanAhmed你应该避免从基础到派生的转换。有时你必须这样做,但更多的时候,你在设计上有缺陷。如果必须经常这样做,那么类就不应该有继承关系。@FarhanAhmed,虽然在这种特定情况下可以这样做,但不建议这样做,这肯定会导致代码设计非常糟糕,但是如果必须这样做,<代码>动态谓词> /COD>更好。考虑使用这种方式,你必须绝对肯定地知道<代码> BASE*/COD>指向一个<代码>派生的<代码>,如果你绝对知道这一点,你为什么要使用<代码> BASE< /COD>?@ FarhanAhmed,我把更多的信息添加到我的答案中,一定要去看看。
main.cpp: In function ‘int main()’:
main.cpp:34:25: error: ‘class Base’ has no member named ‘DoSomething’
pBase->DoSomething();
^
main.cpp:36:12: error: ‘class Base’ has no member named ‘b’
pBase->b = 0.2f;
^
class Base
{
public:
int a;
float b;
virtual ~Base(){} //virtual destructor required
virtual void DoSomething() //implementing DoSomething in base class
{
std::cout << "Base";
}
};
class Derived : public Base
{
public:
void DoSomething() override //override DoSomething() in base class
{
std::cout<<"Derived";
}
};
Base * pBase = new Derived();
//Base will choose the most suited DoSomething(), depending where it's pointing to
pBase->DoSomething();
pBase->a = 5;
pBase->b = 0.2f;