模板类中函数定义应当全部放在头文件中

本文解释了C++模板定义的独特之处及其实例化的机制。通过《C++编程思想》一书的内容,介绍了模板如何在编译期间处理,并探讨了模板实例化过程中消除多重定义的方法。
《C++编程思想》第15章(第300页)说明了原因:模板定义很特殊。由template<…>处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。
在C++中,模板类中的成员函数模板是可以将声明与定义分离的,但需要遵循一定的规则。通常,模板定义(包括成员函数模板定义)需要在头文件中可见,因为编译器需要在编译时对模板进行实例化。然而,通过一些技巧,可以实现模板声明与定义的分离。 ### 成员函数模板的声明与定义分离 在类模板中,成员函数模板的声明通常位于类的定义中,而其定义(即函数体)可以放在类外,甚至可以放在另一个源文件中。但为了使编译器能够正确地进行模板实例化,通常需要将模板定义也保留在头文件中,或者通过显式实例化来处理。 例如,以下是一个类模板中成员函数模板的声明与定义分离的示例: ```cpp // header.h #pragma once template <typename T> class MyClass { public: template <typename U> void process(U value); }; // 成员函数模板定义 template <typename T> template <typename U> void MyClass<T>::process(U value) { // 处理逻辑 } ``` 在上述代码中,`MyClass` 是一个类模板,其中包含一个成员函数模板 `process`。该函数的声明位于类模板定义中,而其定义则位于类模板的外部。 ### 显式实例化 如果希望将模板定义放在单独的源文件中,则可以使用显式实例化。显式实例化允许在特定的编译单元中生成特定类型的模板实例,从而避免将模板定义暴露给所有使用该模板源文件。 ```cpp // source.cpp #include "header.h" // 显式实例化 template class MyClass<int>; template void MyClass<int>::process<double>(double); ``` 在这个例子中,`source.cpp` 文件中显式实例化了 `MyClass<int>` 以及其成员函数模板 `process<double>`,这样其他源文件就可以直接使用这些实例化的版本,而不需要访问模板定义[^4]。 ### 注意事项 尽管可以将模板定义与声明分离,但在实际开发中,为了简化代码管理和避免链接错误,通常建议将模板定义也保留在头文件中。这样做可以确保编译器在需要的时候能够访问到模板的完整定义,从而正确地进行模板实例化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值