存档在 2013年3月23日

为什么C++编译器不能支持对模板的分离式编译

2013年3月23日

为什么C++编译器不能支持对模板的分离式编译

刘未鹏(pongba)

首先,一个编译单元(translation unit)是指一个.cpp文件以及它所#include的所有.h文件,.h文件里的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个.obj文件(假定我们的平台是win32),后者拥有PE(Portable Executable,即windows可执行文件)文件格式,并且本身包含的就已经是二进制码,但是不一定能够执行,因为并不保证其中一定有main函数。当编译器将一个工程里的所有.cpp文件以分离的方式编译完毕后,再由连接器(linker)进行连接成为一个.exe文件。 » 阅读更多: 为什么C++编译器不能支持对模板的分离式编译

类模板的成员函数为什么不能分离式编译

2013年3月23日

以下的代码是为了定义一个具有回调功能的类,并进行测试。为了针对任意类型都可使用,我们使用模板来泛化这个类,定义如下:
serial.h

#ifndef SERIAL_H_
#define SERIAL_H_
template
class Serial
{
	typedef  void(T::*Func)(void);
public:
	Serial();
	~Serial();
	void setTObject(T* t);
	void setCallBackFunc(Func tFunc);
	void callFunc();
private:
	T* tObject;
	Func func;
};
#endif

serial.cpp

#include "serial.h"
#include
using namespace std;

template Serial::Serial(){}
template Serial::~Serial(){}

template
void Serial::setTObject(T* t)
{
		tObject = t;
}
template
void Serial::setCallBackFunc(Func tFunc)
{
	func = tFunc;
}

template
void Serial::callFunc()
{
	(tObject->*func)();
}

robot.h

#ifndef ROBOT_H_
#define ROBOT_H_
#include
using namespace std;
class Robot
{
public:
	void myFunc(void){cout<<"测试"<<endl;}
};
#endif

main.cpp

#include "robot.h"
#include "serial.h"
#include
using namespace std;

int main()
{
	Serial mySerial;
	Robot *robot = new Robot();
	mySerial.setTObject(robot);
	mySerial.setCallBackFunc(&Robot::myFunc);
	mySerial.callFunc();
	delete robot;
}

出现编译错误如下

/tmp/ccuMoBaX.o: In function `main':
main.cpp:(.text+0x13): undefined reference to `Serial::Serial()'
main.cpp:(.text+0x37): undefined reference to `Serial::setTObject(Robot*)'
main.cpp:(.text+0x55): undefined reference to `Serial::setCallBackFunc(void (Robot::*)())'
main.cpp:(.text+0x61): undefined reference to `Serial::callFunc()'
main.cpp:(.text+0x79): undefined reference to `Serial::~Serial()'
main.cpp:(.text+0x95): undefined reference to `Serial::~Serial()'

» 阅读更多: 类模板的成员函数为什么不能分离式编译