为什么没有像我期望的那样使用映射调用复制构造函数?
我在使用带有 std::map 的自定义类时遇到问题。该类动态地为成员分配内存,我不想在映射中使用指针,因为我想确保该类负责删除所有分配的内存。但我遇到的问题是在将项目添加到地图后,当该代码块超出范围时,即使它仍在地图上,也会调用对象析构函数。我在下面编写了一段假代码来说明我的意思。输出是: 那么问题是为什么最终的析构函数被调用?预先感谢并抱歉问了这么长的问题。
Constructor Called Num:0034B7E8
Default Constructor Called Num:00000000
Copy Constructor Called Num:CCCCCCCC
Copy Constructor Called Num:CDCDCDCD
destructor called Num:CCCCCCCC
destructor called Num:00000000
destructor called Num:0034B7E8
Inserted Num:0034B7E8
class myClass
{
public:
myClass(int num)
{
mnNum = new int();
cout << "Constructor Called Num:" << mnNum << endl;
}
myClass() : mnNum(NULL)
{
cout << "Default Constructor Called Num:" << mnNum << endl;
}
myClass(const myClass ©)
{
mnNum = new int(copy.mnNum);
cout << "Copy Constructor Called Num:" << mnNum << endl;
}
~myClass()
{
delete mnNum;
mnNum = NULL;
}
int* mnNum;
};
map<string,myClass> mvMyMap;
void testFunction()
{
myClass lcObj(1);
mvMyMap["Test"] = lcObj;
}
int _tmain(int argc, _TCHAR* argv[])
{
testFunction();
cout << "Inserted Num:" << mvMyMap["Test"].mnNum << endl;
return 0;
}
I am having problems using my custom class with a std::map. The class dynamically allocates memory for members, and I do not want to use pointer in the map because I want to ensure that the class takes care of deleting all allocated memory. But the problem I am having is after I add item to map, when that block of code goes out of scope, the objects destructor is called even though it is still on the map. I made a fake bit of code below that shows what I mean. The output is: So the problem is why is the final destructor being called? Thanks in advance and sorry for the long question.
Constructor Called Num:0034B7E8
Default Constructor Called Num:00000000
Copy Constructor Called Num:CCCCCCCC
Copy Constructor Called Num:CDCDCDCD
destructor called Num:CCCCCCCC
destructor called Num:00000000
destructor called Num:0034B7E8
Inserted Num:0034B7E8
class myClass
{
public:
myClass(int num)
{
mnNum = new int();
cout << "Constructor Called Num:" << mnNum << endl;
}
myClass() : mnNum(NULL)
{
cout << "Default Constructor Called Num:" << mnNum << endl;
}
myClass(const myClass ©)
{
mnNum = new int(copy.mnNum);
cout << "Copy Constructor Called Num:" << mnNum << endl;
}
~myClass()
{
delete mnNum;
mnNum = NULL;
}
int* mnNum;
};
map<string,myClass> mvMyMap;
void testFunction()
{
myClass lcObj(1);
mvMyMap["Test"] = lcObj;
}
int _tmain(int argc, _TCHAR* argv[])
{
testFunction();
cout << "Inserted Num:" << mvMyMap["Test"].mnNum << endl;
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
除了复制构造函数之外,
myClass
还需要自定义赋值运算符。因此,当您进行分配时,您将泄漏左侧的原始值,并最终双重删除右侧的值。myClass
needs a custom assignment operator, in addition to the copy constructor. So when you make an assignment, you'll leak the original value on the left, and eventually double delete the value on the right.您的构造函数会忽略
num
参数,并且永远不会从中初始化mnNum
。它应该看起来像:您还需要像这样调整您的复制构造函数:
编辑
Derek Ledbetter 指出我们也需要一个赋值运算符。我建议将析构函数设为虚拟。
Your constructor ignores the
num
parameter and never initializesmnNum
from it. It should look like:You also need to adjust your copy constructor like this:
edit
Derek Ledbetter pointed out that we need an assignment operator, too. And I would suggest making the destructor virtual.