动态_cast<&燃气轮机;使用Stroustrup示例的问题 我在StruouStrup C++第四ED页642中测试了一个动态的例子,它没有编译。我直接从书中使用下面的图片,试图了解它是如何工作的。有人知道这是埃拉塔(不是在他出版的勘误表文档中)还是我误读了什么吗
Stroustrup图形,虚线表示受保护:动态_cast<&燃气轮机;使用Stroustrup示例的问题 我在StruouStrup C++第四ED页642中测试了一个动态的例子,它没有编译。我直接从书中使用下面的图片,试图了解它是如何工作的。有人知道这是埃拉塔(不是在他出版的勘误表文档中)还是我误读了什么吗,c++,c++11,C++,C++11,Stroustrup图形,虚线表示受保护: 这个错误解释了什么是错的。动态强制转换仅允许用于多态类型(除非在继承层次结构中向上强制转换) 类只有在至少有一个虚函数时才是多态的I没有任何虚拟功能。因此它不是多态的。您必须在I中添加一个虚拟函数才能工作 请注意,即使如此,dynamic_cast(&ii)也永远不能是非空指针(即true),因为ii不是H类型的对象的基本子对象。你需要在类中的某个地方添加关键字virtual,使其具有多态性。我认为virtual(根据本书最后一节)是指两个类共享一个
这个错误解释了什么是错的。动态强制转换仅允许用于多态类型(除非在继承层次结构中向上强制转换) 类只有在至少有一个虚函数时才是多态的<代码>I没有任何虚拟功能。因此它不是多态的。您必须在
I
中添加一个虚拟函数才能工作
请注意,即使如此,
dynamic_cast(&ii)
也永远不能是非空指针(即true),因为ii
不是H
类型的对象的基本子对象。你需要在类中的某个地方添加关键字virtual
,使其具有多态性。我认为virtual(根据本书最后一节)是指两个类共享一个共同的基类作为菱形的解决方案?不,virtual
是一个关键字,只有在你使用它时才会发生。它是用来解决钻石问题的,但如果你有钻石,你不会自动得到它。@NathanOliver:我认为你提到了OP,这让OP感到困惑,OP不应该关心它。请参见OP对eerorika答案的评论。因此F类:虚拟公共I{
,这不正确work@notaorb确实不是。这不是一个虚拟函数。所以我添加了类I{virtual void f(void){};
,这就解决了问题。仍然不清楚为什么会解决这个问题。@notaorb添加了澄清。这是一个固定的示例(将虚拟析构函数添加到基类):
#include <iostream>
using namespace std;
// H = Ival_box
class H {
};
// G = Ival_slider
class G : public H {
};
// I = BBwindow
class I {
};
// F = BB_slider
class F : public I {
};
// X = BB_ival_slider
class X : public G, protected F {
};
int main(int argc, char *argv[])
{
// works
X xx{};
if (auto p = dynamic_cast<G*>(&xx))
cout << "X*...G*" << endl;
// works
G gg{};
if (auto p = dynamic_cast<H*>(&gg))
cout << "G*...H*" << endl;
// compilation error, 'I' is not polymorphic
I ii{};
if (auto p = dynamic_cast<H*>(&ii))
cout << "I*...H*" << endl;
return 0;
}
clang++ -std=c++11 -pedantic -Wall test164.cc && ./a.out
test164.cc:31:18: error: 'I' is not polymorphic
if (auto p = dynamic_cast<H*>(&ii))
^ ~~~
1 error generated.
clang++ -std=c++11 -pedantic -Wall test164.cc && ./a.out
X*...G*
G*...H*