我有一个层次结构,其中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
。这样安全吗?第一次调用
doCall()
时,我有一个共享指针。第二次我为std::shared_ptr
分配另一个theBase
时,我想知道:旧指针(第一个调用中的一个)被破坏了,并且创建了一个新指针吗?还是我必须做这样的事情?if (*theBase != nullptr) {
theBase.reset(); //delete the old one;
}
switch (it) { /* ... */}
每次调用
doCall()
时,我必须创建一个新对象,该对象是theBase
的子类。我做得对吗? 最佳答案
你什么都不做。将新创建的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
在创建第二个指针后立即销毁第一个指针(更具体而言,在分配指针时;第一个指针的计数器在此递减)。