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

时间:2017-12-05 23:09:07

标签: c++ c++11 shared-ptr

我有一个层次结构,其中A是一个抽象类,BCDA的后代。我有一个类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。这样安全吗?

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

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

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

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

1 个答案:

答案 0 :(得分:5)

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

第一个指针在创建第二个指针之后被破坏(更具体地说,在分配时;第一个指针在第一个指针递减的位置)。