c++中函数模板和类模板的 声明与定义 实现放在不同的文件

为什么 c++中函数模板和类模板的 声明与定义需要放到一起?

一般来说,模板的声明和定义,都放在同一个头文件里,其它cpp需要用的时候包这个头文件。

 

但是,将模板的声明与定义写在一起实在很不优雅。尝试用“传统”方法,及在.h文件里声明,在.cpp文件里定义,

然后在main函数里包含.h头文件,这样会报链接错误。

这是因为函数模板要被实例化后才能成为真正的函数,在使用函数模板的源文件中包含函数模板的头文件,(carefully!!!)

如果该头文件中只有声明,没有定义,那编译器无法实例化该模板,最终导致链接错误。(类模板同样!!)

//---------------test.h-------------------// 
void f();//这里声明一个函数f 


//---------------test.cpp--------------// 
#include”test.h” 
void f() 
{ 
 …//do something 
} //这里实现出test.h中声明的f函数 


//---------------main.cpp--------------// 
#include”test.h” 
int main() 
{ 
    f(); //调用f
}

编译时会生成两个obj文件,main.obj和test.obj,而在main.obj里并没有f函数的二进制代码,这些代码实际存在于test.obj中。

在main.obj中对 f 的调用只会生成一行call指令,call指令的地址由链接器生成。

 

我们知道模板有个具现化的过程,在未被使用的时候是不会生成二进制文件的。所以当链接器去找f函数的地址时,因为在这之前没有调用过f(),test.obj里自然就没有f函数的二进制代码,于是就会报错。

//-------------test.h----------------// 
template<class T> 
class A 
{ 
  public: 
    void f(); //这里只是个声明 
};
 
//---------------test.cpp-------------// 
#include”test.h” 
template<class T> 
void A<T>::f() 
{ 
…//do something 
} 

//---------------main.cpp---------------// 
#include”test.h” 
int main() 
{ 
    A<int> a; 
    a.f(); 
}

 

要使模板声明与定义分开也不是没有办法。

第1种办法是在main函数里包含实现了模板定义的文件

//-------------test.h----------------// 
template<class T> 
class A 
{ 
  public: 
    void f(); //这里只是个声明 
}; 

//---------------test.cpp-------------// 
#include”test.h” 
template<class T> 
void A<T>::f() 
{ 
…//do something 
}
 
//---------------main.cpp---------------// 
#include”test.cpp” //careful!!!!!!!!!
int main() 
{ 
    A<int> a; 
    a.f(); 
}

这样三个文件的内容通过include实际上包含在同一个文件里,自然就不会出错了

 

第2种办法是,在模板定义文件的末尾,重新声明具现的函数模板(类模板)类型

//-------------test.h----------------// 
template<class T> 
class A 
{ 
  public: 
    void f(); //这里只是个声明 
}; 

/---------------test.cpp-------------// 
#include”test.h” 
template<class T> 
void A<T>::f() 
{ 
…//do something 
} 
template class A<int>;//在这里实现了具现的类型  这样编译就不会有问题了  但是这样不太好
/---------------main.cpp---------------// 
#include”test.h” 
int main() 
{ 
    A<int> a; 
    a.f(); 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值