Ogr*_*m33 4 c++ polymorphism shared-ptr
这是我本周遇到的一个益智游戏.部分原因是我在编写Java一段时间之后刚刚回到C++编码.给出以下代码:
class Base {
};
class A : Base {
public:
virtual void run() { cout << "This is A." << endl; }
};
class B : Base {
public:
virtual void run() { cout << "This is B." << endl; }
};
class C : A, B {
public:
void run() { cout << "This is C." << endl; }
};
int main(int argc, char* argv[])
{
shared_ptr<A> ptrToA = shared_ptr<C>(new C());
cout << "Pointer to A: " << ptrToA.get() << endl;
cout << "Dynamic Cast A ptr to C: " << dynamic_pointer_cast<C>(ptrToA) << endl;
ptrToA->run();
assert(dynamic_pointer_cast<C>(ptrToA));
cout << "Success!" << endl;
}
Run Code Online (Sandbox Code Playgroud)
为什么会产生以下输出?
Pointer to A: 0x1f29c010
Dynamic Cast A ptr to C: 0
Running...
This is C.
tester-cpp: tester.cpp:89: int main(int, char **): Assertion `dynamic_pointer_cast<C>(ptrToA)' failed.
Run Code Online (Sandbox Code Playgroud)
因为打印出"This is C",很明显多态性正在工作,但是当动态将shared_ptr从"A"基类转换为"C"时,它会失败.本周我在这个微妙的问题上浪费了几个小时的时间!希望任何答案都可以避免未来的编码人员浪费这么多时间来解决类似的问题(这个错误非常微妙,特别是在编写Java一段时间之后).
为什么?(我会给你一个提示......这段代码是用Linux上的英特尔C++编译器12.1.0编译的.我用另一个编译器试了一下,我的代码无法编译!)
它无法在另一个编译器上编译的事实是一个提示:它确实应该无法编译.这是因为C私人的继承A和B,所以C*不应该转换为A*.因此shared_ptr<A> ptrToA = shared_ptr<C>(new C());应该无法编译,因为当指针可以根据标准转换时,对话构造函数应该只参与重载解析.所以这看起来像是英特尔C++使用的标准库中的一个错误.
更改Class C: A, B到Class C: public A, public B它应该工作.在gcc 4.6上进行测试,代码确实无法使用私有继承进行编译,并且与公共继承一样工作A.