【问题标题】:Getting shared pointer from this of derived class in C++从 C++ 派生类的 this 获取共享指针
【发布时间】:2020-10-29 12:40:30
【问题描述】:

我想从派生类中获取 shared_ptr。
std::enable_shared_ptr_from_this 由基类继承并获取 std::shared_ptr<Base>,但不是 std::shared<Derived>。我可以使用std::reinterpret_pointer_caststd::dynamic_pointer_cast 但是

  1. 代码太多了
  2. 使用多重继承是否安全?
    还是只有这样?

示例代码:

class Base : public std::enable_shared_from_this<Base> {

};

class Derived : public Base {
public:
    std::shared_ptr<Derived> GetPointer() const {
        return shared_from_this(); // but it returns std::shared<Base> type
    }
};

提前致谢!

【问题讨论】:

  • 我想你或多或少地回答了你自己的问题。您可以使用std::static_pointer_cast,因为您知道确切的类型,因此不需要动态转换。使用“太多代码”作为不以正确方式做某事的论据基本上总是一个不好的借口。在这种情况下,没有其他办法,如果你不进行强制转换,代码将无法编译。所以是的,这是安全的,也是唯一的方法。此外,它几乎没有很多额外的代码。 1 个函数中可能有 30 个额外字符...

标签: c++ stl shared-ptr


【解决方案1】:

按照您目前的方式进行操作非常安全。

#include <memory>

class Base : public std::enable_shared_from_this<Base>{
public:
    virtual int32_t getid() = 0;
};
class Derived : public Base{
public:
    int32_t id;
    Derived(int32_t id){
        this->id = id;
    }
    ~Derived(){
        
    }
    int32_t getid(){
        return id;
    }
};
int main(){
    std::shared_ptr<Derived> child = std::make_shared<Derived>(1033);
    std::shared_ptr<Base> parent = child;//This needs no extra work
    std::shared_ptr<Derived> secondchildinstance = std::static_pointer_cast<Derived>(parent);//this needs casting
    if(secondchildinstance!=nullptr){
        //shared_from_this can be called directly from the child without an explicit method
        std::shared_ptr<Base> secondparentinstance = secondchildinstance->shared_from_this();
        
        //shared_from_this would require downcasting to get the child
        std::shared_ptr<Derived> thirdchildinstance =  std::static_pointer_cast<Derived>(secondchildinstance->shared_from_this());//requires casting
        
        if(thirdchildinstance!=nullptr){
            printf("use count:%ld id:%d",thirdchildinstance.use_count(),thirdchildinstance->getid());
        }
    }
    return 0;
}

您可能可以通过包装方法简化从父级向下转换到子级的工作。

需要注意的是,你不需要显式方法来调用 shared_from_this,因为父级已经继承了它,你可以直接调用 child->shared_from_this() 但它会给出基类的共享实例将需要向下转换。

【讨论】:

  • 这里不需要“昂贵的”动态演员表。你知道指针的确切类型,所以静态转换就可以了。
  • dynamic_pointer_cast 与 static_pointer_cast 相比有多贵?是静态编译时间吗?
  • 你没有完成他的例子。 std::shared_ptr&lt;const Base&gt; GetPointer() const { return std::static_pointer_cast&lt;const Derived&gt;(shared_from_this()); } 为什么这不是用dynamic_pointer_cast 编译的,而是用static 编译的?我很好奇。
  • 我会做出改变
  • @Nina static_cast 的成本非常低,另请参阅此处接受的答案中的第二条评论:stackoverflow.com/questions/6445841/… dynamic_cast 有很大的开销。
猜你喜欢
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
  • 2016-12-02
  • 1970-01-01
相关资源
最近更新 更多