更新:此示例中的shared_ptr与Boost中的一样,但它不支持shared_polymorphic_downcast(或者dynamic_pointer_cast或static_pointer_cast)!
我正在尝试初始化一个派生类的共享指针,而不会丢失引用计数:
struct Base { };
struct Derived : public Base { };
shared_ptr<Base> base(new Base());
shared_ptr<Derived> derived;
// error: invalid conversion from 'Base* const' to 'Derived*'
derived = base;
到现在为止还挺好 . 我没想到C会隐式地将Base *转换为Derived * . 但是,我确实需要代码表示的功能(即,在向下转换基指针时保持引用计数) . 我的第一个想法是在Base中提供一个强制转换运算符,以便可以进行对Derived的隐式转换(对于pedants:我会检查向下转换是否有效,不要担心):
struct Base {
operator Derived* ();
}
// ...
Base::operator Derived* () {
return down_cast<Derived*>(this);
}
好吧,它没有帮助 . 似乎编译器完全忽略了我的类型转换操作符 . 任何想法如何使shared_ptr分配工作?加分: Base* const
是什么类型的? const Base*
我明白了,但 Base* const
?在这种情况下 const
指的是什么?
3 回答
你可以使用
dynamic_pointer_cast
. 它由std::shared_ptr
支持 .另外,我不建议在基类中使用强制转换运算符 . 像这样的隐式转换可能会成为错误和错误的根源 .
-Update:如果类型不是多态的,可以使用
std::static_pointer_cast
.我假设你正在使用
boost::shared_ptr
......我想你想dynamic_pointer_cast或shared_polymorphic_downcast
.但是,这些需要多态类型 .
const Base *
是一个指向常量Base
的可变指针 .Base const *
是一个指向常量Base
的可变指针 .Base * const
是一个指向可变Base
的常量指针 .Base const * const
是一个指向常量Base
的常量指针 .这是一个最小的例子:
我不确定你的例子是否有意创建基类型的实例并将其强制转换,但它可以很好地说明差异 .
static_pointer_cast
将"just do it" . 这将导致未定义的行为(Derived*
指向由Base
分配和初始化的内存)并且可能导致崩溃,或者更糟 .base
上的引用计数将递增 .dynamic_pointer_cast
将导致空指针 .base
上的引用计数将保持不变 .shared_polymorphic_downcast
将与静态强制转换具有相同的结果,但会触发断言,而不是看似成功并导致未定义的行为 .base
上的引用计数将递增 .见(dead link):
If somebody gets here with boost::shared_ptr...
这是您可以向下转换为派生的Boost shared_ptr的方法 . 假设Derived继承自Base .
确保'Base' class / struct至少有一个虚函数 . 虚拟析构函数也可以工作 .