这是我第一次在课堂上使用Template。这是我的尝试。
MyCairoControl.h:
#ifndef _MYCAIROCONTROL_
#define _MYCAIROCONTROL_
template<class T>
class MyCairoControl : public IControl
{
private:
T *pPlug;
public:
MyCairoControl(T *plug, IRECT container);
~MyCairoControl();
};
#endif // !_MYCAIROCONTROL_
MyCairoControl.cpp:
#include "MyCairoControl.h"
MyCairoControl::MyCairoControl(T *plug, IRECT container) : IControl(plug, container), pPlug(plug) {
// t->somethings();
}
MyCairoControl::~MyCairoControl() {
}
但它说&#34; T&#34;未定义,所以我无法使用该CTOR。不是在课堂上使用模板的正确方法吗?
答案 0 :(得分:3)
由于MyCairoControl
是类模板,因此其方法定义也必须是模板,与类的模板参数匹配:
template <class T>
MyCairoControl<T>::MyCairoControl(T *plug, IRECT container){
/* ... */
}
template <class T>
MyCairoControl<T>::~MyCairoControl() {
/* ... */
}
这也意味着定义总是必须在编译期间可用,而不是链接 - 它们需要存在于头文件中。
This article (&#34;如何在.h文件中定义模板类并在.cpp文件中实现&#34;)对该问题进行全面解释。
答案 1 :(得分:1)
您需要在实现文件中重新声明T
作为模板类型名称:
#include "MyCairoControl.h"
template<class T>
MyCairoControl<T>::MyCairoControl(T *plug, IRECT container) : IControl(plug, container), pPlug(plug) {
// t->somethings();
}
template<class T>
MyCairoControl<T>::~MyCairoControl() {
}
最初的问题是双重问题。首先,T
作为符号需要被称为模板参数。添加到实现签名的template<class T>
行执行此操作 - 它定义了T
的含义。其次,您需要意识到构造函数和析构函数(实际上是任何成员)所属的类型不再是MyCairoControl
而是MyCairoControl<T>
。范围解析运算符的左侧现在需要是。
还有一个值得注意的问题。就目前而言,类成员的实现与标题位于一个单独的文件中,这可能会产生问题。该类的消费者将包括标题而不是源文件,因此他们将无法使用该模板 - 例如,如果他们尝试使用MyCairoControl<Foo>
,他们将得到未解决的符号错误。如果您知道将用于T
的类型,则可以修复此问题。具体而言,如果您在MyCairoControl.cpp
中声明专业化,如下所示:
template <>
class MyCairoControl<Foo>;
template <>
class MyCairoControl<Bar>;
任何人都可以使用MyCairoControl<Foo>
和MyCairoControl<Bar>
,但尝试使用MyCairoControl<OtherType>
仍会提供未解决的外部符号错误,直到您为其添加前向声明。