向下转型 shared_ptr<Base>到 shared_ptr<Derived>?

2021-12-18 00:00:00 gcc c++ boost

更新:本例中的 shared_ptr 与 Boost 中的类似,但它不支持 shared_polymorphic_downcast(或 dynamic_pointer_cast 或 static_pointer_cast)!

我试图在不丢失引用计数的情况下初始化一个指向派生类的共享指针:

struct Base { };结构派生:公共基础{};shared_ptr基地(新基地());shared_ptr衍生的;//错误:从Base* const"到Derived*"的无效转换派生 = 基础;

到目前为止,一切都很好.我没想到 C++ 会隐式地将 Base* 转换为 Derived*.但是,我确实想要代码表达的功能(即,在向下转换基指针的同时维护引用计数).我的第一个想法是在 Base 中提供一个强制转换运算符,以便可以进行到 Derived 的隐式转换(对于学究:我会检查向下转换是否有效,别担心):

struct Base {运算符派生* ();}//...Base::operator Derived* () {return down_cast(this);}

好吧,它没有帮助.编译器似乎完全忽略了我的类型转换运算符.有什么想法可以让 shared_ptr 分配工作吗?补充一点:Base* const 是什么类型的?const Base* 我明白,但是Base* const?在这种情况下,const 指的是什么?

解决方案

您可以使用 dynamic_pointer_cast.std::shared_ptr 支持它.

std::shared_ptr基础(新派生());std::shared_ptr派生 =std::dynamic_pointer_cast(根据);

文档:https://en.cppreference.com/w/cpp/内存/shared_ptr/pointer_cast

另外,我不建议在基类中使用强制转换运算符.像这样的隐式转换可能会成为错误和错误的来源.

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

Update: the shared_ptr in this example is like the one in Boost, but it doesn't support shared_polymorphic_downcast (or dynamic_pointer_cast or static_pointer_cast for that matter)!

I'm trying to initialize a shared pointer to a derived class without losing the reference count:

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;  

So far, so good. I didn't expect C++ to implicitly convert Base* to Derived*. However, I do want the functionality expressed by the code (that is, maintaining the reference count while downcasting the base pointer). My first thought was to provide a cast operator in Base so that an implicit conversion to Derived could take place (for pedants: I would check that the down cast is valid, don't worry):

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

Well, it didn't help. It seems the compiler completely ignored my typecast operator. Any ideas how I could make the shared_ptr assignment work? For extra points: what kind of type Base* const is? const Base* I understand, but Base* const? What does const refer to in this case?

解决方案

You can use dynamic_pointer_cast. It is supported by std::shared_ptr.

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

Documentation: https://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast

Also, I don't recommend using cast operator in the base class. Implicit casting like this may become the source of bugs and errors.

-Update: If the type is not polymorphic, std::static_pointer_cast may be used.

相关文章