C++ 按基类对象访问派生类资源时出错

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

我有一个基类叫做base,还有一个基类的派生类叫做derived, 基类指针可以指向派生类对象,也可以访问其资源,但我在执行相同操作时遇到错误

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
派生的类指定。经过一点研究,我发现我正在寻找静态cast
static_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;