首页 > 解决方案 > DerivedA 指向 DerivedB 的指针

问题描述

我有一个用作接口的基类(如果我正确使用该词)。这个想法是基类有一些实现基类的一个虚函数的派生类。然后我还需要另一个扩展基类的类(我们称之为扩展基类)。我想要的是我可以将从基派生的类存储到扩展基指针中。

MWE:

class Base {
public:
    virtual ~Base();
    virtual double value();
}
class Derived : public Base{
public:
    double value() override {return 5;}
}
class ExtendedBase : public Base {
public:
    virtual ~ExtendedBase ();
    virtual double value2(){return 10;}
}

int main() {
    ExtendedBase * object;
    object = new Derived();
    std::cout << object->value(); //should give implementation in Derived, i.e. 5
    std::cout << object->value2(); //should give implementation in ExtendedBase, i.e. 10
    delete object;
    return 0;
}

使用这个 MWE,我在主文件的第二行出现编译错误。error: cannot convert 'Derived*' to 'ExtendedBase*' in assignment object = new Derived();. 我的一部分理解为什么它不起作用(尽管我无法解释),但我想知道我是否可以通过其他方式获得所需的行为。

PS抱歉问题名称不好,我想不出另一种方法来保持简短

PS2 我知道不建议使用这样的原始指针。将来我会改用智能指针,但我认为这个简单的例子不需要

标签: c++c++11inheritance

解决方案


当您将地址分配给指针时,这意味着您应该能够通过指针访问指针指向的类型的所有成员。

例如,

class B {};
class D : B {};

B *p = new D();

现在通过p,至少您可以访问派生类的基部分的所有成员。

但在你的代码中,

ExtendedBase * object;
object = new Derived();

对象应该能够访问派生类的 ExtendedBase 部分的所有成员。但是怎么可能,因为派生类不是从 ExtendeBase 派生的。所以编译器抛出错误。

您需要对代码进行一些更改才能正常工作。

  1. 要将base作为接口(抽象类),您需要将至少一个成员函数定义为纯虚函数。
  2. 如果要通过 Base 指针访问 ExtendedBase 的成员函数,则应在 ExtendedBase 中定义相同的函数 'val'。

以下是更改。

#include <iostream>

using namespace std;

class Base {
    public:
        virtual ~Base() {};
        virtual double value() = 0;
};

class Derived : public Base{
    public:
        ~Derived() {};
        double value() {
            return 5;
        }
};

class ExtendedBase : public Base {
    public:
        virtual ~ExtendedBase () {};
        double value()
        {
            return 10;
        }
};
    
int main() {
    Base *p = new Derived();
    std::cout << p->value() << std::endl;
    delete p;

    Base *p1 = new ExtendedBase();
    std::cout << p1->value() << std::endl;
    delete p1;

    return 0;
}

推荐阅读