C++ shared_ptr 释放多个引用

C++ shared ptr release on multiple references

我有一个层次结构,其中 A 是抽象 class,BCDA 的后代.我有一个 class 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.

的值使用继承得到我需要的class

假设我调用这段代码:

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

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

当我第一次调用doCall()时,我有一个共享指针。我第二次将另一个 std::shared_ptr 分配给 theBase,我想知道:旧指针(第一次调用的指针)是否被销毁并创建了一个新指针?或者我必须做这样的事情吗?

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

switch (it) { /* ... */}

每次调用 doCall() 时,我都必须创建一个新对象,它是 theBase 的子 class。我做得对吗?

你什么都不用做。当您将新创建的 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

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