您的位置:首页 > 其它

读《模板的声明和实现为何要放在头文件中?》有感

2012-06-11 11:23 302 查看
先看一个普通类的生成顺序:

//test.h

#ifndef _TEST_ 
#define _TEST_
#include <iostream>
#include <string>

class Test 
{
public:
	Test(int m);
	~Test();

	void sum(int n);

private:
	int m;
};

#endif


//test.cpp

#include "test.h"

Test::Test(int m)
{
	this->m = m;
}

Test::~Test()
{

}

void Test::sum(int n)
{
	std::cout<<m+n<<std::endl;
}
//main.cpp

#include "test.h"

int main()
{
 	Test t(5);
	t.sum(3);
	system("pause");
	return 0;
}
编译器首先编译main.cpp生成main.obj,执行到Test t(5)是,到test.h中查找整个类的定义,由于test.h中全是声明,所以main.obj只能处于监听(我暂且这样思考)。编译test.cpp生成test.obj,通知main.obj的监听,定义已经编译完了,存在定义。main.obj得到定义,连接obj,生成exe。

来看看模板:

//test.h

#ifndef _TEST_ 
#define _TEST_
#include <iostream>
#include <string>

template<typename T>
class Test 
{
public:
	Test(T m);
	~Test();

	void sum(T n);

private:
	T m;
};

#endif


//test.cpp

#include "test.h"

template<typename T>
Test<T>::Test(T m)
{
	this->m = m;
}

template<typename T>
Test<T>::~Test()
{

}

template<typename T>
void Test<T>::sum(T n)
{
	std::cout<<m+n<<std::endl;
}


//main.cpp

#include "test.h"

#include "test.h"

int main()
{
 	Test<int> t(5);
	t.sum(3);
	system("pause");
	return 0;
}
编译出错!因为main.obj在test.h没有找到定义之后发起一个监听(我的理解),编译器就去编译test.cpp了。由于在test.cpp中没有模板具现化的代码(没有与Test<int>匹配的定义),也就没有能响应main.obj监听的通知,main.obj就不能实例化Test<int> t(5)这个对象,因为找不到定义。

如果:

#include "test.cpp"

int main()
{
 	Test<int> t(5);
	t.sum(3);
	system("pause");
	return 0;
}
直接包含test.cpp的话,main.obj就先到test.cpp中查找,这不是一个监听的过程,是一个主动的查找过程,直接匹配带入一下,找到合适定义,就能生成对象了,程序也就能成功执行了。这样有一个缺点,在main.cpp中包含了test.cpp和test.h,内容过大,想想看都不舒服。

为了让main.obj能直接找到Test<int>的定义,那就把Test<T>的声明和定义都放在同一个文件中把。这样比直接包含cpp美观点。

个人思维,可能不严谨。

原文地址:模板的声明和实现为何要放在头文件中?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: