从基到派生的shared_ptr的C++dynamic_ptr_cast失败
C++ dynamic_ptr_cast of a shared_ptr from a base to derived fails
这是我本周遇到的一个难题。这在一定程度上是因为在对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;
}
为什么它会产生以下输出?
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.
因为"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
的公共继承一样工作。
由于您的代码包含菱形继承,您可能还想了解一下虚拟继承。
相关文章:
- 如何理解C++标准N3337中的expr.const.cast子句8
- C++Cast运算符过载
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 错误:"cast"未命名类型void setCastDescription(std::string
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- 通过使用 const-cast 的非常量引用来延长临时的寿命
- "(void) cast"与功能有什么区别 "__attributes__"来沉默未使用的参数警告?
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题