std :: multimap的问题

时间:2009-10-05 11:52:50

标签: c++

我有以下内容:

enum Type 
{ One = 0, Two};

class MySubClass
{
private:
MySubClass(); // prohibited
MySubClass(const MySubClass&); // prohibited
MySubClass & operator (const MySubClass&); // prohibited
public :
MySubClass(int x);
};

class MyClass 
{
MyClass(int x) : m_x(new SubClass(x)) 
{}
~MyClass() 
{ delete m_x; }
private :
MySubClass * m_x;
};

typedef multimap<Type, MyClass> my_multimap;
typedef pair<Type, MyClass> my_pair;

我正在尝试执行以下操作:

my_multimap my_map;
my_map.insert(my_pair(One, MyClass(5)));

我得到一个未处理的异常结果,该应用程序正在尝试读取0xfeeefeee等。

发生了什么事?我怎样才能解决这个问题? 请注意,这是我正在处理的简化案例;

4 个答案:

答案 0 :(得分:5)

有一条经验法则,称为“三个规则”:每当你有一个析构函数或赋值运算符或一个复制构造函数时,你很可能需要它们全部三个。您的代码也不例外。

考虑复制类型对象时会发生什么。这个

MyClass obj1;
MyClass obj2(obj1);

代码也会崩溃。

答案 1 :(得分:4)

MyClass没有定义复制构造函数。但是,std::pair需要使用MyClass的复制构造函数。据推测它正在使用MyClass的默认复制构造函数,它将为复制构造对象提供指针m_x的副本。当它们被摧毁时,你将面临多次删除。

答案 2 :(得分:1)

你必须写一个复制构造函数。

正在发生的事情是,MyClass是按值复制的 指针在副本之间共享。 现在当物体被摧毁了 指针被删除倍数。

像这样:

class MyClass 
{
MyClass(int x) : m_x(new SubClass(x)) {}
MyClass(const MyClass& myclass) : m_x(new SubClass(*myclass.m_x)) {}
~MyClass() { delete m_x; }
private :
MySubClass * m_x;
};

显然,SubClass也需要一个复制构造函数。

答案 3 :(得分:1)

正如大家所提到的,类需要一个工作副本构造函数才能存储在任何标准容器中。但是,在这种情况下,MySubClass禁用复制。这几乎有两个选择:

1)MyClass也应该是不可复制的,在这种情况下你必须在多图中存储(智能)指针。

2)复制的MyClass实例应共享MySubClass实例。要实现这一点,最简单的方法是用boost::shared_ptr<MySubClass>std::tr1::shared_ptr<MySubClass>替换指针成员。这样做可以使您免于执行析构函数,复制构造函数和赋值运算符的任务。

相关问题