代码之家  ›  专栏  ›  技术社区  ›  Raffaele Rossi

C++在多个引用上共享ptr版本

  •  0
  • Raffaele Rossi  · 技术社区  · 7 年前

    我有一个层次结构 A 是一个抽象类 B , C D 是的后代 A. . 我有课 Controller (MVC模式),具有指向 A. :

    class Controller {
    
    private: 
     int it;
     std::shared_ptr<A> theBase;
    
    public:
     void doCall();
    //more code
    
    }
    

    在…内 doCall() 我这样做:

    void doCall() {
    
      switch (it) {
        case 4:
          theBase = std::make_shared<B>( B(8) );
          break;
        case 3:
          theBase = std::make_shared<C>( C(6) );
          break;
        default:
          theBase = std::make_shared<D>( D(0) );
          break;
        }
    
      theBase->method();
    
    }
    

    通过这种方式,我可以正确使用智能指针,并且可以根据 it .

    假设我将此代码称为:

    Controller x;
    x.doCall();
    x.doCall();
    

    我在打电话 doCall() 两次,所以我要去 switch 两次这意味着 std::make_shared 被调用两次并分配给 theBase . 这安全吗?

    当我打电话时 我第一次有了一个共享指针。第二次我分配另一个 std::shared_ptr theBase公司 ,我想知道:旧指针(第一个调用的指针)是否被销毁,而新指针是否被创建?还是我必须这样做?

    if (*theBase != nullptr) {
      theBase.reset(); //delete the old one;
    }
    
    switch (it) { /* ... */}
    

    每次 doCall() 调用时,我必须创建一个新对象,该对象是 theBase公司 . 我做得对吗?

    1 回复  |  直到 7 年前
        1
  •  5
  •   Asen Valchev    7 年前

    你什么都不用做。当您指定新创建的 shared_ptr theBase ,旧的参考计数器将递减。然而,旧的计数器是1(如果我们假设您没有在其他地方引用它)。计数器达到0,并调用析构函数。

    请看以下代码:

    #include <stdio.h>
    #include <memory>
    
    class myClass
    {
    public:
        myClass(int i) : m_i(i) { printf("Constructed %d\n", m_i); }
        ~myClass() { printf("Destructed %d\n", m_i); }
    
        int m_i;
    };
    
    int main()
    {
        std::shared_ptr<myClass> ptr = std::make_shared<myClass>(5);
    
        ptr = std::make_shared<myClass>(10);
    }
    

    输出为:

    Constructed 5
    Constructed 10
    Destructed 5
    Destructed 10
    

    第一个指针在创建第二个指针后立即被销毁(更具体地说是在赋值时;这就是第一个指针的计数器递减的地方)。