首页 > 解决方案 > 基类的指针如何用于形成派生类对象?

问题描述

我的测验中有这个问题。你能解释一下吗?

指向基类的指针可以用派生类的地址初始化,因为______。

正确的答案是“指针的派生到基础的隐式转换”。

我有一些与此代码相关的问题:

#include <iostream>
using namespace std;

class Base
{
    protected:
    int x;
    public:
    Base(){};
    Base(int x1): x(x1) {};
    void show()
    {
        cout<<"x = "<<x<<endl;
    }
    virtual void printData()
    {
        cout<<"x = "<<x<<endl;
    }

};

class Derived: public Base
{
    int y;
    public:
    Derived(){};
    Derived(int x1, int y1): Base(x1), y(y1) {};
    void showXY()
    {
        cout<<"x = "<<x<<endl;
        cout<<"y = "<<y<<endl;
    }
    void printData()
    {
        cout<<"x = "<<x<<endl;
        cout<<"y = "<<y<<endl;
    }
    
    
};

int main()
{
    Base *d1 = new Derived(1,2);
    // d1->showXY(); gives error in running a derived class function
    d1->show();  // runs a base class function
    d1-> printData(); // runs a virtual (overriden) derived class function
    d1->~Base();  // uses a base class destructor

}

请解释一下这个概念。它是基类对象还是派生类对象?因为它运行基类函数,但如果有覆盖,那么它运行派生类函数,但在运行纯派生类函数时会出错。

标签: c++classobjectpointersc++17

解决方案


是基类对象还是派生类对象

派生类对象是动态创建的。那是对象的动态类型。派生对象包含一个基础子对象。d1指向基础子对象。那是指针的静态类型。

d1->~Base();

这很糟糕,原因有两个:

  • 行为未定义,因为析构函数是非虚拟的
  • 内存泄露了。这里不应该显式调用析构函数,而是delete应该使用(如果析构函数是虚拟的)。

推荐阅读