微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

DerivedA 指针指向 DerivedB

如何解决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();。我的一部分理解为什么它不起作用(虽然我无法解释),但我想知道我是否可以通过其他方式获得所需的行为。

附言对不起,问题名称不好,我想不出另一种方法来保持简短

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

解决方法

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

例如,

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

B *p = new D();

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

但是在您的代码中,

ExtendedBase * object;
object = new Derived();

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

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

  1. 要将基类作为接口(抽象类),您需要在 至少一个成员函数是纯虚函数。
  2. 如果你想通过以下方式访问ExtendedBase的成员函数 基指针,你应该在你的 扩展基础。

以下是变化。

#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;
}
,

ExtendedBaseDerived 均源自 Base。如果要使用 ExtendedBase* 指针指向 Derived 对象,则需要从 Derived 派生 ExtendedBase

换个例子,

class Feline{
   virtual void run();
}

class Housecat : Feline{
   void run() {}
}

class BigCat : Feline{
   virtual void run();
   virtual void roar();
}

此处的 FelineHousecatBigCat 类似于 BaseDerivedExtendedBaseBigCatHousecat 都是 Feline,但由于 Housecat 不是 BigCat,您不能使用 BigCat* 指针指向Housecat

,

从语言架构师的角度来看,这是理想的行为。 例如,如果你有

class Ship
{
    public:
        virtual void move() = 0;
}

class Steamboat : public Ship
{
    public:
        virtual void move() override { ... }
}

class Sailboat : public Ship
{
    public:
        virtual void move() override { ... }
        virtual void setSails() { ... }
}

现在,您不希望汽船突然变成帆船,因此:

Steamboat* tootoo = new Sailboat;

无效。 这就是您的代码无法工作的原因。从概念上讲。 因此无法快速修复,因为您的概念不是很清楚。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。