c++模板类成员的声明和定义

时间:2021-11-08 14:24:58

c++模板类成员的声明和定义应该都放在*.h中,有普通类不一样。

如果定义放在*.cpp中,最终链接时,会报方法undefined错误。

参考:http://users.cis.fiu.edu/~weiss/Deltoid/vcstl/templates

 

如果非要定义在*.cpp中,一定要具体化模板类型,如下,但这样意味着你要定义无数个。

所以还是放在*.h中吧,用到的地方,编译器会帮你定义具体类型的方法。

// error
template<typename T>
A<T>::func() {
// ...
}

// OK
template<>
A<int>::func() {
// ...
}

  

一个例子:

// template.h

#include <iostream>
#ifndef __TEMPLATE_H_
#define __TEMPLATE_H_

class ContextAbstr {
public:
virtual void log() = 0;
};

template
<typename T>
class Sam {
public:
Sam() {}
virtual ~Sam() {}

void func() {
_context.log();
return;
}

public:
static int snumber;
static void sfunc();

private:
T _context;
};

// template class's method must be define in *.h
// so when be called, different T expand to different definetion
// otherwise, ld cann't find the method
template<typename T>
void Sam<T>::sfunc() {
std::cout
<< "hello template static func" << std::endl;
}

// regular class's method be declared in *.h, and defined in *.cpp
// otherwise, result to mutli-definetion error
class Context : public ContextAbstr {
public:
void log();
};

#endif //__TEMPLATE_H_

// template.cpp

#include "template.h"

// template class's member also can be defined in *.cpp, but must specilize the T
template<>
int Sam<int>::snumber = 10;

template
<>
int Sam<float>::snumber = 15;

// regular class's method be defined in *.cpp, avoid mutli-definetion
void Context::log() {
std::cout
<< "hello world from template class" << std::endl;
}

// test_template.cpp

#include "template.h"

int main()
{
Sam
<Context>::sfunc();

Sam
<Context>* sam = new Sam<Context>();
sam
->func();

Sam
<int>* sam_int = new Sam<int>();
std::cout
<< "int's snumber: " << sam_int->snumber << std::endl;

Sam
<float>* sam_float = new Sam<float>();
std::cout
<< "float's snumber: " << sam_float->snumber << std::endl;

return 0;
}