C++ 销毁具有指针值的映射的正确方法

C++ 销毁具有指针值的映射的正确方法,c++,pointers,stl,C++,Pointers,Stl,我正在使用std::map将字符串值映射到MyType*。我的地图声明如下所示: map<string, MyType *> *my_map = new map<string, MyType>; 这将删除映射中包含的指针,还是需要在调用erase之前遍历映射以删除每个指针?指针仅指向一个指针。使用原始指针时,您需要知道应用程序的哪个部分拥有指针指向的资源。如果它们属于映射,则在销毁映射之前,需要在映射上迭代并对每个指针调用delete。但是,如果映射只包含指向代码其他部

我正在使用
std::map
将字符串值映射到
MyType*
。我的地图声明如下所示:

map<string, MyType *> *my_map = new map<string, MyType>;

这将删除映射中包含的指针,还是需要在调用erase之前遍历映射以删除每个指针?

指针仅指向一个指针。使用原始指针时,您需要知道应用程序的哪个部分拥有指针指向的资源。如果它们属于映射,则在销毁映射之前,需要在映射上迭代并对每个指针调用delete。但是,如果映射只包含指向代码其他部分所拥有的对象的指针,则无需执行任何操作

一个更安全的解决方案是使用shared_ptr来管理对象的生存期,这将确保在销毁最后一个shared_ptr时正确删除对象。您可以将共享的\u ptr存储在地图中,如果没有其他共享的\u ptr实例引用地图中的对象,则当地图被销毁时,这些对象将根据需要被销毁。

如果您使用原始指针而不是原始指针,则会自动为您清理所有内容

// header:
using MapType = std::map<std::string, std::shared_ptr<MyType>>;
shared_ptr<MapType> my_map;

// usage:
my_map.emplace("foo", std::make_shared<MyType>());

// destructor:
MyClass::~MyClass()
{
    // nothing!
}
//标题:
使用MapType=std::map;
共享我的地图;
//用法:
my_map.emplace(“foo”,std::make_shared());
//析构函数:
MyClass::~MyClass()
{
//没什么!
}
这会删除映射[…]中包含的指针吗

不,根据您提供的代码,您将泄漏地图的每个成员

通常,对于每个
必须有一个匹配的
delete
。地图有一个
delete
,但其中的元素没有

解决这个问题最正确的方法是根本不使用动态分配。如果可能,只需存储MyType的目录即可:

map

。。。而不是动态分配
地图
本身,而是自动存储:

map<string,MyType> my_map;
(给定一个C++03编译器,使用它的Boost等价物。)然后当
my_map
被销毁时,所有元素都将
delete
d

尽管如此,如果您处于上述任何一项都不适用于您的情况下(我高度怀疑),那么您需要自己迭代地图:

struct deleter
{
  template <typename T> operator() (const T& rhs) const
  { 
    delete rhs.second;
  }
};

for_each (my_map->begin(), my_map->end(), deleter());

在现代C++中,只需使你的生活更简单,只在严格要求时使用指针。 您从以下代码开始:

如果您真的需要一个包含指针的映射,考虑使用<强>智能指针,如<代码> STD::SysDypPTR <代码>(可在C++ 11/14中)共享所有权,或<代码> STD::UNQuYGYPTR <代码>以获得唯一的非共享所有权。 (如果您的目标是C++98/03,一个选项是使用

boost::shared_ptr
。因为没有移动语义,所以不能有
unique_ptr
,这在很大程度上是基于移动语义特性的。)
e、 g:

//包含智能指针的映射
//-->默认析构函数正常(无需自定义删除代码)
绘制我的地图;

如您所见,使用值语义(而不是原始指针)或智能指针,可以简化代码并使用C++提供的<>强>自动销毁< /强> <> < <代码> map (以及标准库中的大多数(如果不是全部)容器)未设计为在销毁时删除其包含的任何指针。好的,谢谢。我在上面读到的文档不是很清楚。它是这样写的:

这有效地减少了容器的大小,减少了被删除的元素的数量,这些元素被破坏。
这是一个常见的误解-指针本身确实被破坏了,但这不会改变它们指向的内存位置的状态。为什么痴迷于指针和
新的
?这有什么不对:
map my\u map设计中出现了一些错误。为什么容器拥有指针?
map<string, unique_ptr<MyType>> my_map;
struct deleter
{
  template <typename T> operator() (const T& rhs) const
  { 
    delete rhs.second;
  }
};

for_each (my_map->begin(), my_map->end(), deleter());
for_each (my_map->begin(), my_map->end(), [](auto item) -> void
{
  delete item.second;
});
map<string, MyType *> *my_map = new map<string, MyType>;
// my_map data member - no pointers --> automatically deleted in class destructor
map<string, MyType> my_map;
// Map containing _smart_ pointers 
//     --> default destructor is fine (no need for custom delete code)
map<string, shared_ptr<MyType>> my_map;