我想初始化一个共享的指针指向一个派生类不失引用计数:
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
是指在这种情况下?
您可以使用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
可以使用。
我假设你正在使用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);
我不知道这是否是故意的,你的例子创建基本类型的实例,并施放它,但它起到很好的说明了差异。
该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的...
这是你如何向下转换到派生升压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;
确保“基地”类/结构至少具有一个虚函数。 虚析构函数也适用。