Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::multimap的问题_C++ - Fatal编程技术网

C++ std::multimap的问题

C++ std::multimap的问题,c++,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 MyCla

我有以下几点:

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等

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

您必须编写一个复制构造函数

发生的事情是,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;
};

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

您必须编写一个复制构造函数

发生的事情是,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;
};

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

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

想象一下复制类型的对象时会发生什么。这个

MyClass obj1;
MyClass obj2(obj1);

代码也会崩溃

有一条经验法则,称为“三法则”:无论何时,只要有析构函数、赋值运算符或复制构造函数,都很可能需要这三个。您的代码也不例外

想象一下复制类型的对象时会发生什么。这个

MyClass obj1;
MyClass obj2(obj1);

代码也会崩溃

MyClass
未定义复制构造函数。但是,
std::pair
将需要使用
MyClass
的复制构造函数。大概它使用的是
MyClass
的默认复制构造函数,它将为复制构造的对象提供指针
mux
的副本。当它们被销毁时,您将面临多次删除。

MyClass
没有定义复制构造函数。但是,
std::pair
将需要使用
MyClass
的复制构造函数。大概它使用的是
MyClass
的默认复制构造函数,它将为复制构造的对象提供指针
mux
的副本。当它们被销毁时,您将面临多次删除。

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

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


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

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

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


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

您不需要“禁止”默认构造函数,因为提供手写构造函数可以有效地防止编译器生成默认构造函数。通过这样做,您可以在没有实现的情况下实际使用默认构造函数(来自您的类或朋友)。您不需要“禁止”默认构造函数,因为提供手写构造函数可以有效地防止编译器生成默认构造函数。通过这样做,您可以在没有实现的情况下实际使用默认构造函数(来自您的类或朋友)。即使在显示的代码中可能没有使用默认构造函数,这仍然会错过赋值运算符。此外,派生类不需要定义复制构造函数,生成的编译器也可以。即使在显示的代码中可能没有使用它,这仍然会丢失赋值运算符。此外,派生类不需要定义复制构造函数,生成的编译器也可以。