C++ - 将模板的声明和定义放置在同一个头文件里

本文介绍模板类的三种实现方式:头文件内联、分离编译与使用export关键字。探讨不同方法的优缺点及支持情况,并解释export的工作原理。
1. 一个类:
头文件用于保存类的声明;定义文件保存程序的实现。

2. 分离编译模式:
允许在一个编译单元(.cpp文件)中定义函数、类型、类对象等,然后在另一个编译单元中引用它们。编译器处理完所有的编译单元后,链接器接下来会处理所有指向extern符号的引用(有时为缺省),从而生成单一可执行文件。

3. 模板类型:
模板类性不是一种实类型,它必须等到类型绑定后才能确定最终类型,所以在实例化一个模板时,必须要能够让编译器“看到”在哪里使用了模板,而且必须看到模板确切的定义,而不仅仅是它们的声明,都则不能顺利地产生编译代码。因此,标准会要求模板的实例化与定义体放到同一编译单元中。

4. 三种方法:
(1)模板的声明和定义都放置在同一个.h文件中(最好):
// Temp.h
template <class T>
class Temp
{
public:
    void set_value(const T & rT);
protected:
private:
    T m_value;
};

template <class T>
void Temp<T>::set_value(const T & rT)
{
    m_value = rT;
}

(2)声明和实现分离,包含.cpp文件:
// Temp.h
template <class T>
class Temp
{
public:
    void set_value(const T & rT);
protected:
private:
    T m_value;
};

// Temp.cpp
#include "Temp.h"

template <class T>
void Temp<T>::set_value(const T & rT)
{
    m_value = rT;
}

// main.cpp
#include "Temp.cpp"  // 包含.cpp文件

注意:不是所有编译器都支持此做法。

(3)使用export使声明实现分离:
// Temp.h
template <class T>
class Temp
{
public:
    void set_value(const T & rT);
protected:
private:
    T m_value;
};

// Temp.cpp
#include "Temp.h"

export template <class T>
void Temp<T>::set_value(const T & rT)
{
    m_value = rT;
}

// main.cpp
#include "Temp.h"  // 包含.h文件

注意:并非所有编译器都支持export关键字,且性能太差。

5. export原理:
在编译过程中,编译器会像.NET和Java那样,为模板实体生成一个“中间伪代码(IPC)”,使其他编译单元在实例化时可以找到定义体;而在遇到实例化时,则根据指定的实参再将此IPC重新编译,从而达到分离编译的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值