关于STL中MAP的奇怪表现,求解惑

此帐号已弃用12 2013-10-22 06:00:38
废话不说,先上代码

#include "stdafx.h"
#include "windows.h"
#pragma warning(disable: 4786)
#include <string>
#include <map>
class Ctest
{
public:
Ctest(){OutputDebugString("\n 构造");};
virtual ~Ctest(){OutputDebugString("\n 析构");};
int m_nTest;
};

int main(int argc, char* argv[])
{
std::map<int,Ctest> m_TestMap;
m_TestMap[0];
getchar();
getchar();
return 0;
}


运行后得到结果

构造
析构
析构


我所理解的应该只会得到

构造


后面出现两个“析构”是怎么回事,求大能解惑.
...全文
189 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
mujiok2003 2013-10-23
  • 打赏
  • 举报
回复
取决于实现和优化, 比如这个
  • 打赏
  • 举报
回复
多谢各位的解答,昨天下班回家了,初步了解了这个问题应该是由于MAP的树结构造成的。
ztenv 版主 2013-10-23
  • 打赏
  • 举报
回复
如果说初次接入stl,建议先学学语法及使用注意事项,不建议陷入其中,当然如果感觉自己对C++语言的语法(模板、指针等等)和很多算法(map内部使用的是红黑树)都清楚了,可以看看stl源码,否则不太建议看,里面还是有些难度的。
ztenv 版主 2013-10-23
  • 打赏
  • 举报
回复
引用 10 楼 wangdahu888 的回复:

#include "stdafx.h"
#include "windows.h"
#pragma warning(disable: 4786)
#include <string>
#include <map>
class Ctest
{
public:
	Ctest(){
		OutputDebugString(L"\n 构造");
	}
	Ctest(const Ctest& t){
		OutputDebugString(L"\n  拷贝构造");
	}

	virtual ~Ctest(){
		OutputDebugString(L"\n 析构");
	}
	int m_nTest;
};
void test(){


	std::map<int,Ctest> m_TestMap;
	m_TestMap[0];
}
int main(int argc, char* argv[])
{
   test();
	getchar();
	return 0;
}
输出是: 构造 拷贝构造 拷贝构造 析构 析构
你的输出是不完整的,还有一个临时对象没有释放,不可能构造三次,只释放两次; 另外如果要明白为什么,可能真的要看看map的源码的; 一般情况下map中最好别存对象,尤其是带指针成员的对象(否则应该重写拷贝机制,有多种实现方式,比如:引用计数、深拷贝等)和大的对象(拷贝耗时间,效率低下),建议map中存储对象的指针,记得自己清理资源就好。
  • 打赏
  • 举报
回复

#include "stdafx.h"
#include "windows.h"
#pragma warning(disable: 4786)
#include <string>
#include <map>
class Ctest
{
public:
	Ctest(){
		OutputDebugString(L"\n 构造");
	}
	Ctest(const Ctest& t){
		OutputDebugString(L"\n  拷贝构造");
	}

	virtual ~Ctest(){
		OutputDebugString(L"\n 析构");
	}
	int m_nTest;
};
void test(){


	std::map<int,Ctest> m_TestMap;
	m_TestMap[0];
}
int main(int argc, char* argv[])
{
   test();
	getchar();
	return 0;
}
输出是: 构造 拷贝构造 拷贝构造 析构 析构
flyrack 2013-10-22
  • 打赏
  • 举报
回复
只构造一次 析构两次 那还有一次是谁析构的??
ri_aje 2013-10-22
  • 打赏
  • 举报
回复
std::map 在 main} 的时候析构了,同时析构了其包含的所有元素,所以 m_TestMap[0] 创建的 Ctest 对象也析构了。
derekrose 2013-10-22
  • 打赏
  • 举报
回复
要了解原理去看stl源码 析构函数 http://www.tech-recipes.com/rx/1231/c-destructor/
qyxqyxqyx 2013-10-22
  • 打赏
  • 举报
回复
m_TestMap[0];这句话执行的时候,输出了

 构造
 复制构造
 复制构造
 析构
 析构
所有结果
qyxqyxqyx 2013-10-22
  • 打赏
  • 举报
回复
引用 4 楼 WillMyPower 的回复:
我的疑问是我并没有释放,怎么就会执行到析构函数了? 求解释MAP的高深知识
m_TestMap[0]会在平衡树中查找有木有0,发现木有,会构造一个临时对象,这个临时对象在这句分号结尾生命周期结束。同时,在这句话里头还会有拷贝操作,这个你懂的,在树中存在
  • 打赏
  • 举报
回复
我的疑问是我并没有释放,怎么就会执行到析构函数了? 求解释MAP的高深知识
  • 打赏
  • 举报
回复
引用 1 楼 lianshaohua 的回复:
建议你再加上拷贝构造函数、重载=操作符,并打印,再运行一遍你的程序
我是楼主,添加复制构造函数后


#include "stdafx.h"
#include "windows.h"
#pragma warning(disable: 4786)
#include <string>
#include <map>

class Ctest
{
public:
	Ctest(){OutputDebugString("\n 构造");};
	Ctest(const Ctest& anther){OutputDebugString("\n 复制构造");m_nTest = anther.m_nTest;};
	virtual ~Ctest(){OutputDebugString("\n 析构");};
	int m_nTest;
};

int main(int argc, char* argv[])
{
	std::map<int,Ctest> m_TestMap;
	m_TestMap[0];
	getchar();
	getchar();
	return 0;
}
输出结果

 构造
 复制构造
 复制构造
 析构
 析构
turing-complete 2013-10-22
  • 打赏
  • 举报
回复
不要忽略了拷贝构造
ztenv 版主 2013-10-22
  • 打赏
  • 举报
回复
建议你再加上拷贝构造函数、重载=操作符,并打印,再运行一遍你的程序

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧