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

Raf*_*ssi 0 c++ shared-ptr c++11

我有一个层次结构中A是一个抽象类B,C以及D为后代A.我有一个类Controller(MVC模式)与共享指针A:

class Controller {

private: 
 int it;
 std::shared_ptr<A> theBase;

public:
 void doCall();
//more code

}
Run Code Online (Sandbox Code Playgroud)

在里面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();

}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,我可以正确使用智能指针,我可以使用继承来根据值获取我需要的类it.

假设我调用此代码:

Controller x;
x.doCall();
x.doCall();
Run Code Online (Sandbox Code Playgroud)

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

当我doCall()第一次打电话时,我有一个共享指针.第二次,我将另一个std::shared_ptrtheBase,我不知道:是旧的指针(第一次调用的一个)摧毁,新建一个?或者我必须做这样的事情?

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

switch (it) { /* ... */}
Run Code Online (Sandbox Code Playgroud)

每次doCall()调用时,我都要创建一个新的对象,它是一个子类theBase.我做得对吗?

Ase*_*hev 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);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Constructed 5
Constructed 10
Destructed 5
Destructed 10
Run Code Online (Sandbox Code Playgroud)

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