【问题标题】:How to declare an "unknown" derived class as base class as a member and allow the derived version of member function to be called?如何将“未知”派生类声明为基类作为成员并允许调用派生版本的成员函数?
【发布时间】:2018-04-06 19:35:17
【问题描述】:

我目前正在尝试将类 (myClass) 的成员设置为基类的某些派生类 (Derived1、Derived2...)。由于类不知道是哪个派生类,所以成员类型设置为基类,构造时才设置为派生类。

派生类都有一个共同的成员函数,但实现方式不同(基类有一个虚拟版本)。但是,当从 myClass 调用 this 函数时,它总是调用基类版本而不是派生类。

class Base
{
public:
    Base(){}
    virtual void who() { cout << "this is Base"; }
}

class Derived1 : public Base
{
public:
    Derived1() : Base() {}
    void who() { cout << "this is Derived1"; }
}

class myClass
{
private:
    Base unknownDerived;
public:
    myClass(const Base& inputDerived) { unknownDerived = inputDerived; }
    void whosthere() { unknownDerived.who(); }
}

上面的输出是“this is Base”,而是调用了 Base 类版本。

有没有办法在不指定实际派生类的情况下包含成员,但能够调用其特定函数( who() )?

非常感谢!

【问题讨论】:

  • 您没有展示如何运行此代码。请包括main
  • 你的unknownDerived 是sliced
  • @MadPhysicist 主要是myClass test; test.whosthere();
  • @Kevin 有没有办法避免这种情况?因为确切的派生类在构造之前是未知的
  • @alam。我没有看到一个空的构造函数。

标签: c++ virtual base derived-class


【解决方案1】:

当您将 Base 声明为成员时,Base 就是您实际得到的。即使您为其分配了 Derived 类型,您也会体验到所谓的“切片”,即只复制派生对象的 Base 部分,而您的对象仍然是 Base。

在 C++ 中,多态性仅通过指针引用起作用。

要在 myClass 中创建一个真正的成员对象(不是对对象的间接),您需要使 myClass 有一个模板参数,并且您可以在编译时决定它将是什么类型。否则,您必须使用指针和/或引用。

现在您必须清楚内存所有权和适当的清理。您可以让调用者转移对象的所有权(通过获取 unique_ptr),或者您可能坚持 Base 具有虚拟 clone() 函数来创建对象的深层副本。此外,您很可能还需要在基类中使用虚拟析构函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 2017-06-19
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多