用于删除 Map 中的指针值和指针向量的 C++ 通用代码

Posted

技术标签:

【中文标题】用于删除 Map 中的指针值和指针向量的 C++ 通用代码【英文标题】:C++ Generic code for deleting pointer value in Map and vector of pointers 【发布时间】:2011-11-22 17:27:44 【问题描述】:

我有一些通用代码用于删除向量中的指针或 Map 的值。

有没有更好的方法(不使用 shared_ptrs 或任何 tr1 扩展)?

代码也正确吗?

这是我的代码:

我有一个命名空间

#ifndef CONTAINERDELETE_H
#define CONTAINERDELETE_H

#include <functional>
#include <map>
#include <vector>
#include <algorithm>


namspace ContainerDelete

  template<class A, class B>
    struct DeleteMap
    
      bool operator()( pair<A,B> &x) const
      

        delete x.second;
        return true;
      
    ;

   template<class T>
    struct DeleteVector
    
      bool operator()(T &x) const
         
          delete x;
          return true;
        
    ;
 
 #endif

然后我会在一些代码中使用这个命名空间来删除​​地图或矢量。

测试地图删除。

#include "ContainerDelete.h"

using namespace std;

// Test function.
void TestMapDeletion()

   // Add 10 string to map.
   map<int,B*> testMap;
   for( int Idx = 0; Idx < 10; ++Idx )
   
     testMap[Idx] = new B();
   

   // Now delete the map in a single  line.
   for_each( testMap.begin(),
             testMap.end(),
             ContainerDelete::DeleteMap<int,B*>());

测试向量删除

// Test Function.
void TestVectorDeletion()

  // Add 10 string to vector.
  vector<B*> testVector;
  for( int Index = 0; Index < 10; ++Index )
  
    testVector.push_back( new B());
  

  // Now delete the vector in a single  line.
  for_each( testVector.begin(),
            testVector.end(),
            ContainerDelete::DeleteVector<B*>());
 

谢谢,

迈克

【问题讨论】:

shared_ptr 现在是标准的(gcc 4.5 和 VS2010 都支持它),但是如果您不想在完全符合编译器的情况下使用它,您可以使用几乎相同的 boost::shared_ptr。我建议不要实施您自己的解决方案,因为有很多棘手的极端情况(除非您这样做是为了教育目的,这很好)。 在 C++11 中,第一次尝试总是将元素类型设为 std::unique_ptr&lt;T&gt;,并且仅在不符合您的需求时才寻找替代方案。原始指针的容器总是一个坏主意,因为您不知道谁拥有指向的对象。您甚至可能混合了指向动态、静态和自动变量的指针。容器如何能够限制你可以造成的伤害量? @KerrekSB 我在当前代码设置中遇到的主要问题是删除指针的顺序(当我通过引用传递指针时)。我需要确保我从最后一个引用向后工作,以免获得悬空指针?这是使用shared_ptr的好地方吗 @MWright:我不关注。顺序有什么关系?指向的对象是否相互认识?这听起来像是一场维护噩梦...... @KerrekSB 抱歉不清楚。我在我的代码中使用了很多指向指针的指针和指向指针向量的指针。这些对象也通过引用传递给其他类,因此我需要跟踪它们。这些指针是常规指针而不是智能指针。使用 shared_ptr 咬住构建和重新编码以便适当处理我的内存是否符合我的最大利益? 【参考方案1】:

如果将通用性降低为:

struct DeleteVector

    template<class T>  //use the template here!
    void operator()(T &x) const
     
      delete x;
    
;

如果你这样做,那么你可以简单地写这个:

for_each(testVector.begin(),
         testVector.end(),
         ContainerDelete::DeleteVector());

使用DeleteVector时无需传递类型参数,因为它不再是类模板!

同样,你可以实现DeleteMap函子。

您还应该将DeleteVector 重命名为DeleteT,并将DeleteMap 重命名为DeletePairSecond,因为这两个都可以更通用地使用。例如,DeleteT 甚至可以与std::list 一起使用,甚至可以与数组一起使用。

【讨论】:

这看起来确实更干净。我不需要在重载的运算符 () 中返回吗? 但是你声明它返回一个布尔值,应该是无效的吧? @BleepBloop:哎呀。是的。这只是一个错字。 我以为我快疯了!谢谢【参考方案2】:

代码没问题。我无法想象任何其他方法来删除指针。您所能做的就是像上面的问题一样减少显式类型规范。我知道另一种更丑陋的方法:函数推断其模板参数的类型。因此,您可以使用第一个参数 - 向量,第二个 - ptr 编写模板函数,然后使用向量参数的 std::bind 使该函数接受一个参数 - ptr。 但函子更好,更灵活。

【讨论】:

共享指针可能非常慢。如果您不大量复制指针,最好使用它们。

以上是关于用于删除 Map 中的指针值和指针向量的 C++ 通用代码的主要内容,如果未能解决你的问题,请参考以下文章

C ++通过索引删除指针向量中的值[关闭]

在 C++ 中创建指针向量或指针值映射时遇到问题

C++ map删除所有元素 指针 泄露内存

没有指针的 C++ 分段错误 (HackerRank)

如何使用 C++ 中的指针通过指针传递多维向量?

C++中的指针和向量