更新:此示例中的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;
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.我没想到C++会隐式地将Base*转换为Derived*.但是,我确实需要代码表示的功能(即,在向下转换基指针时保持引用计数).我的第一个想法是在Base中提供一个强制转换运算符,以便可以进行对Derived的隐式转换(对于pedants:我会检查向下转换是否有效,不要担心):
struct Base {
operator Derived* ();
}
// ...
Base::operator Derived* () {
return down_cast<Derived*>(this);
}
Run Code Online (Sandbox Code Playgroud)
好吧,它没有帮助.似乎编译器完全忽略了我的类型转换操作符.任何想法如何使shared_ptr分配工作?加分:什么类型Base* const? const Base*我理解,但是Base* const?const在这种情况下指的是什么?
Mas*_*ari 89
你可以用dynamic_pointer_cast.它得到了支持std::shared_ptr.
std::shared_ptr<Base> base (new Derived());
std::shared_ptr<Derived> derived =
std::dynamic_pointer_cast<Derived> (base);
Run Code Online (Sandbox Code Playgroud)
另外,我不建议在基类中使用强制转换运算符.像这样的隐式转换可能会成为错误和错误的根源.
-Update:如果类型不是多态的,std::static_pointer_cast可以使用.
Tim*_*ter 46
我假设你正在使用boost::shared_ptr......我想你想要dynamic_pointer_cast或者shared_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);
Run Code Online (Sandbox Code Playgroud)
我不确定你的例子是否有意创建基类型的实例并将其强制转换,但它可以很好地说明差异.
该static_pointer_cast会"只管去做".这将导致未定义的行为(Derived*指向分配和初始化的内存Base)并且可能导致崩溃,或者更糟.引用计数base将增加.
该dynamic_pointer_cast会导致空指针.引用计数base将保持不变.
在shared_polymorphic_downcast将具有相同结果作为静态的演员,但会触发一个断言,而似乎获得成功,并导致不确定的行为.引用计数base将增加.
见(死链接):
有时候决定是否使用
static_cast或者有点困难dynamic_cast,并且你希望你可以拥有两个世界.众所周知,dynamic_cast具有运行时开销,但它更安全,而static_cast根本没有开销,但它可能会无声地失败.如果可以shared_dynamic_cast在调试版本和shared_static_cast发布版本中使用它会有多好.好吧,这样的事情已经可以使用了shared_polymorphic_downcast.
如果有人来到这里与boost :: shared_ptr ...
这是您可以向下转换为派生的Boost shared_ptr的方法.假设Derived继承自Base.
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;
Run Code Online (Sandbox Code Playgroud)
确保'Base'类/结构至少有一个虚函数.虚拟析构函数也可以工作.
| 归档时间: |
|
| 查看次数: |
63658 次 |
| 最近记录: |