【问题标题】:Deleting std::map of functions删除函数的 std::map
【发布时间】:2018-01-02 10:14:56
【问题描述】:

我正在尝试删除以下地图:

typedef bool (myClass::*func)(std::vector<std::string> &args);
typedef std::map<std::string, func> myMap;
myMap map; //map of functions in the class 'myClass'

void deleteMap()
{
    for(myMap::iterator it = map.begin(); it != map.end(); ++it)
    {
        delete it->second; //compiler says it->second is non-pointer type
        map.erase(it);
    }
}

'map' 将字符串映射到类 'myClass' 中的函数,并且该函数在其参数中采用字符串向量。

在我尝试删除此映射时,我试图删除指向成员函数的指针,然后擦除迭代器本身。编译器说 it->second 必须是指针类型。在 typdef 'func' 中是指向 myClass:: 的指针,那么为什么会出现此错误?

这是删除函数映射的适当方法吗?

【问题讨论】:

  • 你做了新的成员函数?
  • 为什么要在指针上调用 delete?
  • 看来删除该地图的正确方法是退出该函数。
  • 即使没有编译错误,显示的代码也是有缺陷的,并且保证在递增删除的迭代器后由于未定义的行为而导致崩溃。
  • 您正试图删除代表myClass成员函数的内存。只需花点时间思考一下这其中的含义! delete 仅适用于在堆上动态分配的内存,(成员)函数都在内存的静态只读部分。永远不要尝试删除函数指针。使用eraseclear 清空地图就足够了

标签: c++ pointers stl std stdmap


【解决方案1】:

在我尝试删除此映射时,我试图删除指向成员函数的指针,

这是语言不允许的。您只能在对象指针上调用delete

想想这个。

int (*fptr)(const char *lhs, const char *rhs ) = &std::strcmp;

 // Does it make any sense at all?
 // What would you expect the run time to do with this?
delete fptr;

您的功能可以非常简单。你可以清除地图。

void deleteMap()
{
   map.clear();
}

【讨论】:

    【解决方案2】:

    您不能delete 成员指针,因为它是类实例的一部分。

    您尚未发布将元素添加到 myMap 的代码,但此类代码无法在 func 类型的对象上创建带有 new 的成员指针,这表明 delete 是错误的,因为每个delete 必须与new 匹配。

    您可以直接拨打myMap.clear()删除myMap的内容。

    【讨论】:

      【解决方案3】:

      您在这里误解了一些概念。你使用delete/delete[]分别释放new/new[]分配的内存。

      在这里,您有一个std::map,它存储指向成员函数值的指针。在堆上没有使用new 分配内存,因此您根本不必使用delete 释放内存。

      除此之外,您不需要对每个元素都使用std::map::erase()。相反,您可以使用std::map::clear() 清除std::map,或者让std::map的析构函数自动释放内容。

      【讨论】:

        【解决方案4】:

        有时pointer 可能指代不同类型的指针作为一个整体,但通常,例如在这种情况下,它特别表示数据指针。您的指针是一个成员函数指针,因此它不是您的编译器所指的那种指针类型。

        只有数据指针可以传递给delete 操作符,否则程序是错误的。更具体地说,您只能传递由new 运算符返回的指针值。换句话说,delete 用于释放您使用new 分配的动态内存。

        new 运算符永远不能返回(成员)函数指针,因此new 不可能返回您的函数指针。

        这是删除函数映射的适当方法吗?

        没有。您不能“删除”地图指向的功能。

        map::erase 从映射中删除函数指针,但在删除该迭代器后递增该迭代器具有未定义的行为。因此,无法像您尝试的那样简单地实现循环擦除。

        如果要删除所有指针,只需调用map::clear 会更简单。第三方面,当地图本身被销毁时,所有内容都会自动销毁。

        具有静态存储时长的对象,例如您的地图,在程序结束时会自动销毁,您无法自行删除。

        【讨论】:

          猜你喜欢
          • 2011-01-22
          • 2018-02-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多