[英]Unwanted destruction in C++
我有以下代码:
class A;
typedef map<string, A*> AMap;
AMap _amap;
当我尝试分配新的A并将其保存到地图时:
A a = A(str);
_amap[str] = &a;
然后它会在我的程序结束之前调用A
的析构函数。 (我有一个静态成员用于计算对象,当我想检查有多少个对象时返回零)
但是,当我尝试:
_amap[str] = new A(str);
一切正常,但析构函数没有被调用。 这是为什么?
这两种方法有什么区别?
谢谢。
更新
我使用A*
代替A
是我有另一个AList
,它是一个向量,将存储相同的对象。 我使用指针因为我不想浪费内存。
在第二种情况下,不会调用析构函数,因为您可能永远不会delete
在堆上分配的A
对象。
请考虑使用以下typedef:
typedef map<string, unique_ptr<A>> AMap;
然后,使用std::make_unique
创建对象:
_amap[str] = make_unique<A>(str);
(或者,在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;
然后:
_amap.emplace(make_pair(str, A(str)));
在第一种方法中,您存储自动(“堆栈分配”)变量的地址,这不是一个好主意,除非您知道在其值超出范围之后不会使用地图本身。
在第二种方法中,您调用new
但从不delete
,这当然是资源泄漏。
您应该在没有指针的情况下直接在地图中存储A
实例,或者如果需要指向多态的指针,请存储智能指针,以便在销毁地图期间破坏值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.