溯造型的shared_ptr 对于shared_ptr ?(Downcasting sha

2019-06-21 07:46发布

我想初始化一个共享的指针指向一个派生类不失引用计数:

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 ++库*隐式转换为派生*。 不过,我想用代码表示的功能(即,保持引用计数,同时向下转换的基指针)。 我首先想到的是提供基本转换运算符,这样派生可能发生的隐式转换(为学究:我会检查下投是有效的,不用担心):

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

那么,它并没有帮助。 这似乎编译器完全忽略了我的类型转换操作符。 任何想法如何,我可以使shared_ptr的分配工作? 对于加分:什么样类型的Base* const是什么? const Base*我明白,但Base* const ? 什么是const是指在这种情况下?

Answer 1:

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

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

另外,我不建议在基类中使用转换运算符。 这样的隐式转换可能会成为漏洞和错误的根源。

-更新:如果类型不是多态的, std::static_pointer_cast可以使用。



Answer 2:

我假设你正在使用boost::shared_ptr ......我想你想dynamic_pointer_castshared_polymorphic_downcast

这些都需要多态类型,但是。

什么样类型的Base* const是什么? const Base*我明白,但Base* const ? 什么是const是指在这种情况下?

  • const Base *是一个可变指针到恒定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);

我不知道这是否是故意的,你的例子创建基本类型的实例,并施放它,但它起到很好的说明了差异。

static_pointer_cast将“只管去做”。 这将导致不确定的行为(一个Derived*指向的内存分配和初始化Base ),将可能导致崩溃,或者更糟。 上的引用计数base将递增。

dynamic_pointer_cast将导致空指针。 引用计数base将保持不变。

shared_polymorphic_downcast都会有相同的结果作为静态的演员,但会触发一个断言,而似乎获得成功,并导致不确定的行为。 上的引用计数base将递增。

见(死链接) :

有时它是一个有点难以决定是否使用static_castdynamic_cast ,和你想你可以有两全其美的一点点。 这是众所周知的dynamic_cast具有运行时开销,但它是安全的,而拥有的static_cast根本没有开销,但它可能会默默地失败。 如何很好的将是,如果你能使用shared_dynamic_cast在调试版本,并shared_static_cast在发布版本。 那么,这样的事情已经是可用的,被称为shared_polymorphic_downcast



Answer 3:

如果有人送过来用的boost :: shared_ptr的...

这是你如何向下转换到派生升压shared_ptr的。 假设从碱衍生继承。

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;

确保“基地”类/结构至少具有一个虚函数。 虚析构函数也适用。



文章来源: Downcasting shared_ptr to shared_ptr?
标签: c++ gcc boost