C++中不需要的破坏

laz*_*wei 2 c++ constructor memory-management class object

我有以下代码:

class A;
typedef map<string, A*> AMap;
AMap _amap;
Run Code Online (Sandbox Code Playgroud)

当我尝试分配新的A并将其保存到地图时:

A a = A(str);
_amap[str] = &a;
Run Code Online (Sandbox Code Playgroud)

然后它会A在我的程序结束之前调用析构函数.(我有一个静态成员用于计算对象,当我想检查有多少个对象时返回零)

但是,当我尝试:

_amap[str] = new A(str);
Run Code Online (Sandbox Code Playgroud)

一切正常,但析构函数没有被调用.这是为什么?

这两种方法有什么区别?

谢谢.

更新

为什么我使用的原因A*,而不是A是,我还有一个AList,这是一个载体,将存储在同一个对象.我使用指针因为我不想浪费内存.

cdh*_*wie 6

在第二种情况下,析构函数不叫,因为你可能从来没有deleteA对象,您在堆上分配.

请考虑使用以下typedef:

typedef map<string, unique_ptr<A>> AMap;
Run Code Online (Sandbox Code Playgroud)

然后,使用std::make_unique:创建对象:

_amap[str] = make_unique<A>(str);
Run Code Online (Sandbox Code Playgroud)

(或者,前C++ 14: _amap[str] = unique_ptr<A>(new A(str));)

std::unique_ptr析构函数将确保堆分配的对象被删除,但要注意,这意味着,当_amap被破坏,所有的A地图中的物体会呢!

如果你有其他代码可能需要超过生命周期的指向这些对象的指针,_amap那么请考虑使用shared_ptr<A>(和make_shared<A>).这些是共享所有权智能指针,只有在销毁所有 shared_ptr<A>实例时才会删除对象.

另一方面,如果您只需A要将对象存在于某个地方,那么它们就可以存在于地图中:

typedef map<string, A> AMap;
Run Code Online (Sandbox Code Playgroud)

然后:

_amap.emplace(make_pair(str, A(str)));
Run Code Online (Sandbox Code Playgroud)