Downcasting shared_ptr<Base> to shared_ptr<Derived>?
更新:本例中的共享指针与boost中的共享指针类似,但它不支持共享的多态向下转换(或动态指针转换或静态指针转换)。
我正在尝试在不丢失引用计数的情况下初始化指向派生类的共享指针:
1 2 3 4 5 6 7 | 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++会隐式地把BASIC转换成派生的*。但是,我确实希望代码表示的功能(即,在向下转换基指针时保持引用计数)。我的第一个想法是在基础中提供一个强制转换运算符,以便进行到派生的隐式转换(对于学究:我将检查强制转换是否有效,不用担心):
1 2 3 4 5 6 7 | struct Base { operator Derived* (); } // ... Base::operator Derived* () { return down_cast<Derived*>(this); } |
嗯,没用。似乎编译器完全忽略了我的类型转换运算符。我有什么想法可以让共享的分配工作发挥作用吗?加分:什么类型的
您可以使用
1 2 3 | std::shared_ptr<Base> base (new Derived()); std::shared_ptr<Derived> derived = std::dynamic_pointer_cast<Derived> (base); |
另外,我不建议在基类中使用cast运算符。像这样的隐式强制转换可能成为错误和错误的根源。
-更新:如果类型不是多态的,可以使用
我想你用的是
然而,这需要多态性类型。
what kind of type
Base* const is?const Base* I understand, butBase* const ? What doesconst refer to in this case?
const Base * 是指向常量Base 的可变指针。Base const * 是指向常量Base 的可变指针。Base * const 是指向可变Base 的常量指针。Base const * const 是指向常量Base 的常量指针。
下面是一个最小的例子:
1 2 3 4 5 6 7 8 | struct Base { virtual ~Base() { } }; // dynamic casts require polymorphic types struct Derived : public Base { }; boost::shared_ptr<Base> base(new Base()); boost::shared_ptr<Derived> derived; derived = boost::static_pointer_cast<Derived>(base); derived = boost::dynamic_pointer_cast<Derived>(base); derived = boost::shared_polymorphic_downcast<Derived>(base); |
我不确定您的示例是否有意创建一个基类型的实例并对其进行强制转换,但它可以很好地说明这种差异。
参见(死链接):
Sometimes it is a little hard to decide whether to use
static_cast ordynamic_cast , and you wish you could have a little bit of both worlds. It is well known that dynamic_cast has a runtime overhead, but it is safer, whereas static_cast has no overhead at all, but it may fail silently. How nice it would be if you could useshared_dynamic_cast in debug builds, andshared_static_cast in release builds. Well, such a thing is already available and is calledshared_polymorphic_downcast .
如果有人带着Boost::Shared_ptr来到这里…
这是您可以向下投射到派生的Boost共享指针的方法。假设派生继承自基。
1 2 3 4 5 | boost::shared_ptr<Base> bS; bS.reset(new Derived()); boost::shared_ptr<Derived> dS = boost::dynamic_pointer_cast<Derived,Base>(bS); std::cout <<"DerivedSPtr is:" << std::boolalpha << (dS.get() != 0) << std::endl; |
确保"base"类/结构至少有一个虚拟函数。虚拟析构函数也可以工作。