zoukankan      html  css  js  c++  java
  • std::enable_shared_from_this使用

      玩过C++shared_ptr类型的智能指针的同学,是否有接触过std::enable_shared_from_this,它的出现为我们提供哪些编程方面的便利呢?下面就介绍它。

    一、std::enable_shared_from_this的作用

      按照enable_shared_from_this - C++ Reference (cplusplus.com)文档介绍:继承std::enable_shared_from_this的子类,可以使用shared_from_this成员函数获取自身的shared_ptr指针;该类提供了允许继承类的对象创建指向自身实例的shared_ptr,并且与存在shared_ptr对象共享所有权。什么意思呢?我们接下来通过代码进行介绍。

    二、如何使用std::enable_shared_from_this

      上面已经介绍了,需要定义一个继承类继承这个类,代码如下:

     1 namespace test_enable_shared_from_this{
     2 
     3     class Derived : public std::enable_shared_from_this<Derived>
     4     {
     5     public:
     6         void SetValue(int a)
     7         {
     8             _a = a;
     9         }
    10         int GetValue() const
    11         {
    12             return _a;
    13         }
    14     private:
    15         int _a;
    16     };
    17 
    18 }

      那怎么使用这个继承类呢?我们分别在栈,堆上创建对象,然后调用shared_from_this成员函数返回的对象是啥。

      在栈上使用对象:

    1 int main()
    2 {
    3     using namespace test_enable_shared_from_this;
    4     Derived d;
    5     auto obj = d.shared_from_this();
    6     
    7      return 0;  
    8 }

          

      在栈上创建的对象不能调用该函数,会导致异常抛出:bad_weak_ptr。其实我们可以通过shared_from_this成员函数返回的是shared_ptr就知道不行,那么对象只能在堆上创建。能否裸指针呢?

    1 int main()
    2 {
    3     using namespace test_enable_shared_from_this;
    4     auto d = new Derived;
    5     auto obj = d->shared_from_this();
    6     
    7     return 0;
    8 }

           

      直接在堆上创建对象也不行。我们只能使用智能指针std::shared_ptr和unique_ptr,其实大家应该早就知道是哪个了,这里做详细说明是为了对问题的各种情况都进行验证加深对其使用。接下来我们使用

    std::shared_ptr。

    1 int main()
    2 {
    3     using namespace test_enable_shared_from_this;
    4     auto d = std::shared_ptr<Derived>();
    5     auto obj = d->shared_from_this();
    6    
    7     return 0;
    8 }

           

      

      观察两个对象,完全一模一样。这就是文档上介绍std::enable_shared_from_this提供的一种机制。那我们试试std::unique_ptr:

    int main()
    {
        using namespace test_enable_shared_from_this;
        auto d = std::make_unique<Derived>();
        auto obj = d->shared_from_this();
    
        return 0;
    }

           

       也不行。其实上面三种行不通的方式返回的指针都是空的。如下:

           

      所以使用shared_from_this的继承类对象只能是std::shared_ptr,其他方式都不行,如果误用的话,会导致返回的对象为空而出现其他问题。

    三、std::enable_shared_from_this的继承问题

      我们上面只是继承一层,如果另外一个类继承上面的类,那能够正常使用shared_from_this函数吗?获取的对象是最后继承的吗?

      如下代码验证:

     1 namespace test_enable_shared_from_this{
     2 
     3     class Derived : public std::enable_shared_from_this<Derived>
     4     {
     5     public:
     6         void SetValue(int a)
     7         {
     8             _a = a;
     9         }
    10         int GetValue() const
    11         {
    12             return _a;
    13         }
    14     private:
    15         int _a;
    16     };
    17 
    18     class Derived1 : public Derived
    19     {
    20     private:
    21         int _b;
    22     };
    23 
    24 }

       调用代码如下:

    1 int main()
    2 {
    3     using namespace test_enable_shared_from_this;
    4     auto d1 = std::make_shared<Derived1>();
    5     auto obj = d1->shared_from_this();
    6    
    7     return 0;
    8 }

      

       发现问题没有?虽然d1和obj对象地址一样,但是对象内存包含的成员属性不同。d1有自身的属性成员变量,但是obj没有,只含有基类的属性成员变量。是不是shared_from_this返回的对象中只包含那些直接继承

    std::enable_shared_from_this呢?我们用多继承验证下:

     1 namespace test_enable_shared_from_this{
     2 
     3     class Derived : public std::enable_shared_from_this<Derived>
     4     {
     5     public:
     6         void SetValue(int a)
     7         {
     8             _a = a;
     9         }
    10         int GetValue() const
    11         {
    12             return _a;
    13         }
    14     private:
    15         int _a;
    16     };
    17 
    18     class Derived1 : public std::enable_shared_from_this<Derived1>
    19     {
    20     private:
    21         int _b;
    22     };
    23 
    24     class Derived2 : public Derived, public Derived1
    25     {
    26     private:
    27         int _c;
    28     };
    29 
    30 }
    1 int main()
    2 {
    3     using namespace test_enable_shared_from_this;
    4     auto d2 = std::make_shared<Derived2>();
    5     auto obj = d2->shared_from_this();
    6  
    7     return 0;
    8 }

           

       直接提示执行不明确,这个很好理解,它不知道你究竟返回哪个子类std::shared_ptr。所以,继承类中不能存在多次继承std::enable_shared_from_this。哪个类继承的这个类,就返回这个类实例化的对象。我一般在其他类对象需要共享该类对象的情况下使用,这样该类就直接通过shared_ptr共享自身对象,如果其他类是通过引用或裸指针的方式共享该类,就不会继承这个类。

  • 相关阅读:
    Codeforces Round 546 (Div. 2)
    Codeforces Round 545 (Div. 2)
    Codeforces Round 544(Div. 3)
    牛客小白月赛12
    Codeforces Round 261(Div. 2)
    Codeforces Round 260(Div. 2)
    Codeforces Round 259(Div. 2)
    Codeforces Round 258(Div. 2)
    Codeforces Round 257 (Div. 2)
    《A First Course in Probability》-chaper5-连续型随机变量-随机变量函数的分布
  • 原文地址:https://www.cnblogs.com/smartNeo/p/14766607.html
Copyright © 2011-2022 走看看