为什么C++模板声明与定义要放在同一文件中?

       写了3年多C++程序,很少用到模板,我靠,今天想试一下,照着别人的例子写,什么鬼,怎么都运行不过,仔细比对代码才发现,C++模板的声明与定义必须放到一个文件,.h或者.hpp, 真是颠覆我对C++编程的认知,什么坑爹的语法。网上找资料,看博客,看书,才知道必须这样写,太坑了。

        例如我写的一个A 模板类,A.h文件:

#pragma once
#include <iostream>

using namespace std;

template<class T>
class A
{
public:
	A(T a);
	~A();

	void print();
private:
	T a;
};



template<class T>
A<T>::A(T a)
{
	this->a = a;
}

template<class T>
A<T>::~A()
{
}

template<class T>
void A<T>::print()
{
	cout << this->a << endl;
}


template<class T>换成template<typename T>也可以。

注意:必须把方法的声明和实现都写到.h文件,如果把模板的方法写到.cpp就会运行报错

在main函数中测试,如下:

#include "A.h"

int main()
{
	A<int> obj(23);

	obj.print();

	system("pause");
    return 0;
}

目前在C++相关书籍中一种比较通用的解释是:
       模板定义很特殊。由template<…> 处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。

​      对C++编译器而言,当调用函数的时候,编译器只需要看到函数的声明。当定义类类型的对象时,编译器只需要知道类的定义,而不需要知道类的实现代码。因此,因该将类的定义和函数声明放在头文件中,而普通函数和类成员函数的定义放在源文件中。
       但在处理模板函数和类模板时,问题发生了变化。要进行实例化模板函数和类模板,要求编译器在实例化模板时必须在上下文中可以查看到其定义实体;而反过来,在看到实例化模板之前,编译器对模板的定义体是不处理的——原因很简单,编译器怎么会预先知道 typename 实参是什么呢?因此模板的实例化与定义体必须放到同一翻译单元中。

      

猜你喜欢

转载自blog.csdn.net/yao_hou/article/details/89716350