向下广播shared_ptr <Base>到shared_ptr <Derived>?

更新:本示例中的shared_ptr与Boost中的shared_ptr类似,但不支持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 *。 但是,我确实需要代码表示的function(即在向下转换基指针时保持引用计数)。 我的第一个想法是在Base中提供一个演员操作符,这样就可以隐式转换为Derived(对于书呆子,我会检查演员是否有效,不用担心):

 struct Base { operator Derived* (); } // ... Base::operator Derived* () { return down_cast<Derived*>(this); } 

那么,它没有帮助。 编译器似乎完全忽略了我的types转换运算符。 任何想法如何使shared_ptr作业? 加分: Base* const是什么types的? const Base*我知道,但Base* const ? 在这种情况下const是指什么?

你可以使用dynamic_pointer_cast 。 它由std::shared_ptr支持。

 std::shared_ptr<Base> base (new Derived()); std::shared_ptr<Derived> derived = std::dynamic_pointer_cast<Derived> (base); 

另外,我不build议在基类中使用cast操作符。 这样的隐式转换可能会成为错误和错误的根源。

-Update:如果types不是多态,则可以使用std::static_pointer_cast

我假设你使用boost::shared_ptr …我想你想要dynamic_pointer_castshared_polymorphic_downcast

但是,这些需要多态types。

什么样的Base* consttypes? const Base*我知道,但Base* const ? 在这种情况下const是指什么?

  • const Base *是一个指向const Base *的可变指针。
  • Base const *是一个可变的指针,常量Base
  • Base * const是一个指向可变Base的常量指针。
  • Base const * const是一个常量指针,指向一个常量Base

这是一个最小的例子:

 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); 

我不确定是否有意让您的示例创build一个基本types的实例并进行投射,但它可以很好地说明差异。

static_pointer_cast将“只是做”。 这将导致未定义的行为( Derived*指向分配给内存并由Base初始化的内存),并可能导致崩溃,或者更糟。 base的参考计数将增加。

dynamic_pointer_cast将会产生一个空指针。 base的参考数量将保持不变。

shared_polymorphic_downcast将和静态转换有相同的结果,但是会触发一个断言,看起来会成功并导致未定义的行为。 base的参考计数将增加。

看(死链接) :

有时要决定是使用static_cast还是dynamic_cast有点难,而且希望你能有一点点的两个世界。 众所周知,dynamic_cast具有运行时间开销,但更安全,而static_cast根本没有任何开销,但可能会以静默方式失败。 如果可以在debugging版本中使用shared_dynamic_cast ,并且在发行版本中使用shared_static_cast ,那将会有多好。 那么,这样的事情已经可用,被称为shared_polymorphic_downcast

如果有人来到这里与boost :: shared_ptr ….

这是如何可以downcast派生助推shared_ptr。 假设派生从Baseinheritance。

 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'class / struct至less有一个虚函数。 虚拟析构也可以。