【问题标题】:Casting children classes dynamically动态投射子类
【发布时间】:2020-10-03 02:26:18
【问题描述】:

我有以下课程:

class Base{
public:
    virtual int do_Something();
};

class ChildA : public Base {
public:
    int do_Something();    // ChildA does something
};

class ChildB : public Base {
public:
    int do_Something();    // ChildB does something
};

在我的 main.cpp 中,我想根据用户设置的特定配置创建一个对象 ChildA()ChildB()。 我的尝试,在函数main() 中是:

...
int config = 1; // selected by the user

Base* classe;
std::cout<<typeid(classe).name() << std::endl;     // check class name
if (config==0){
    classe= new ChildA();
}
else if (config==1){
    classe= new ChildB();
    std::cout<<typeid(classe).name() << std::endl;     // check class name
}
...

问题

我希望打印出来的名称会有所不同。相反,输出是:

P4Base

P4Base

【问题讨论】:

  • 什么是renderer?这是 Python 还是 C++ if config==0:
  • 对不起,我更正了。这是classe的课程@
  • This answer 可能会引导您朝着正确的方向前进。
  • @ThomasSablik 谢谢,问题现在应该是正确的。
  • 不,不正确。显然你没有尝试编译它。

标签: c++ class inheritance casting polymorphism


【解决方案1】:

这里的问题是classe (Base *) 不是多态的。这是一个简单的指针。您可以在输出中看到它。在带有 GCC 的 Linux 上,它是:P4Base,指向Base的指针

你想要的是typeid(*classe).name()。输出为6ChildBChildB 类型的对象。

多态不会改变指针的类型(无论是静态类型还是动态类型),但它会改变对象的动态类型。

// check class name 的评论有误。线

std::cout<<typeid(classe).name() << std::endl;

不检查类,只检查指针。

【讨论】:

  • 谢谢。我的目标不是打印的名称是正确的,而是正确的子类被转换。我应该修改 if-else 语句中的转换吗?
  • @maurock 我在您的代码中看不到任何演员表。类型是正确的。你不必做任何事情。 classe-&gt;do_Something() 将调用ChildB::do_Something()
  • 我希望指针指向正确的类。现在,我知道指针总是指向父类Base。相反,当参数config 等于1 时,我希望指针classe 指向ChildB
  • @maurock 指针不指向类。它指向一个实际的对象。 typeid 返回类型。 classe 的类型是Base *,你不能改变它。但它指向ChildB 类型的对象,如您在此处看到的:wandbox.org/permlink/sIphh2GJNWadBBbf
  • 感谢您的解释。我的困惑出现了,因为如果我在标头中初始化一个变量,则无法正确检索。下面的例子展示了int a=1在Base中的初始化和int a=2在ChildB中的初始化。打印此值返回 1 而不是 2 wandbox.org/permlink/7rwi47MrjUjaT40s 也许这需要另一个帖子?