带有自定义比较器的C ++ STL映射,用于存储空指针

时间:2011-05-13 22:47:34

标签: c++

我正在尝试为管理包含指针的STL映射的对象编写复制构造函数,其中键是字符串。但是,当我尝试在地图中插入新值时,指针将设置为NULL:

// ...
for(std::map<std::string, data_base*, order>::const_iterator it = other.elements.begin();
it != other.elements.end(); ++it){
    data_base *t = it->second->clone();
    std::cout << "CLONE: " << std::hex << t << std::endl;
    elements[it->first] = t;
    std::cout << "INSERTED: " << std::hex << elements[it->first] << std::endl;
}
// ...

other是要复制的对象,elements是地图。 clone()方法返回指向新对象的指针(通过new)。

运行上面的代码我得到的结果是:

CLONE: 0xcfbbc0
INSERTED: 0

我不是一个非常有经验的程序员,这个问题可能很容易解决,但我没有找到任何解决方案来搜索它。

非常感谢你的时间。

2 个答案:

答案 0 :(得分:4)

我认为这个代码没有任何问题,除了

std::map<std::string, data_base*, order>::const_iterator it

这里order给出了用于对地图中包含的对进行排序的关键比较器(通常实现为树)。

也许你做错了,让你的[]​​操作符找不到合适的ke,让你的最后一行记录一个带有空ptr的新对。

首先,使用默认的key-comparator(std :: less)尝试不使用order,然后如果它不起作用,请发布order定义和地图声明。如果还不够,只需提供一个简单的完整程序来重现问题。


我刚刚使用默认的key-comparator编写了一个简单的类似测试:

#include <map>
#include <string>
#include <iostream>

struct Data 
{ 
    int k; 

    Data* clone() { return new Data(); }
};

typedef std::map< std::string, Data* > DataMap;

DataMap data_map;


int main()
{
    data_map[ "hello" ] = new Data();
    data_map[ "world" ] = new Data();

    DataMap other_map;

    for( DataMap::const_iterator it = data_map.begin(); it != data_map.end(); ++it)
    {
            Data*t = it->second->clone();
            std::cout << "CLONE: " << std::hex << t << std::endl;
            other_map[it->first] = t;
            std::cout << "INSERTED: " << std::hex << other_map[it->first] << std::endl;
    }

    std::cin.ignore();

    return 0;
}

在VS2010SP1上,输出:

CLONE: 00034DD0
INSERTED: 00034DD0
CLONE: 00035098
INSERTED: 00035098

所以它应该是问题,或者你之前做错了。

答案 1 :(得分:0)

试试这个,以帮助调试问题。我建议仔细检查order函数是否正确。您可以将其删除以使用已知有效的std::less<T>

// ...
typedef std::map<std::string, data_base*, order> string_db_map;
for(string_db_map::const_iterator it = other.elements.begin();
    it != other.elements.end();
    ++it)
{
    data_base *t = it->second->clone();
    std::cout << "CLONE: " << std::hex << t << std::endl;
    std::pair<string_db_map::iterator, bool) result = elements.insert(
        string_db_map::value_type( it->first, t));
    if ( !result.second ) 
    {
        std::cout << "element['" << it->first << "'] was already present, and replaced." << std::endl;
    }
    std::coud << "INSERTED [iterator]: " << std::hex << (*result.first).second << std::endl;
    std::cout << "INSERTED [indexed]: " << std::hex << elements[it->first] << std::endl;
}
// ...