持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
- 与函数模板类似,类也可以通过参数,从而可以构建出一族不同类型的类实例(对象)
- 类模板实参可以是某一类型或常量(仅限于 int 和 enum)
类模板的声明
- 声明类模板与声明函数模板类似,在定义类型参数时候可以使用关键字
class和typename来定义。 - 在类模板内部,成员变量或者成员函数都可以使用 T 当做类型,这与其他类型并没有任何区别
- 除了 Copy 构造函数之外,如果在类模板中需要使用到这个类本身,比如定义
operator=,那么应该使用其完整的定义(MyStack<T>),而不是省略类型T, 如下面的例子所示:
template <class T>
class className {
private:
T var;
... .. ...
public:
T functionName(T arg);
... .. ...
};
- 类模板定义,也是通过关键字
template随后跟着模板参数,模板参数放在一对尖括号<>中 - 其中模板参数
T是类型参数,接收一个类型
const std::size_t DefaultStackSize = 1024;
template<typename T, std::size_t n = DefaultStackSize > class MyStack {
public:
void Push(const T const& elem);
int Pop(T& elme);
int Top(T& elem) const;
private:
std::vector<T> m_Members;
std::size_t m_nMaxSize = n;
};
-
T 可以是任意类型,也就是模板类型参数
-
模板实参也可以是一个
int或enum类型的常量,这里size_t本质也就是一个int类型 -
n是编译时定义的常量,可以定义模板时为其指定默认值 -
size_t类型的成员变量可以用 n 初始化 -
类模板的实现,要定义一个类模板的成员函数,则要指明其是一个模板函数,例如
Push函数的定义应当如下:
template<typename T,std::size_t nMaxSize>
void MyStack<T, nMaxSize>::Push(const T const& element)
{
if (m_Members.size() >= m_nMaxSize) {
return;
}
m_Members.push_back(element);
}
如果要是把成员函数写在声明体之外,就需要模板类需要添加上 template<typename T,std::size_t nMaxSize>。
类模板的使用
MyStack<int> my_stack;
my_stack.Push(1);
MyStack<MyStack<int> > intMyStackStack;
MyStack<int> my_stack定义了一个类型为int的MyStack大小默认值为 1024,- 可以在初始化时候传入
MyStack<int, 100> my_stack_2;来定义类型为int大小为100的MyStack需要注意MyStack<MyStack<int> > intMyStackStack;需要在>两个之间留有一个空格,不要>>这样写,如果这样写可能会认为操作符。
多参数模板
template <class T, class U, class V = int>
class ClassName {
private:
T member1;
U member2;
V member3;
... .. ...
public:
... .. ...
};
#include <iostream>
using namespace std;
// 类模板带有多个参数以及类型参数带有默认值
template <class T, class U, class V = char>
class ClassTemplate {
private:
T var1;
U var2;
V var3;
public:
ClassTemplate(T v1, U v2, V v3) : var1(v1), var2(v2), var3(v3) {} // constructor
void printVar() {
cout << "var1 = " << var1 << endl;
cout << "var2 = " << var2 << endl;
cout << "var3 = " << var3 << endl;
}
};
int main() {
// 创建一个使用 int, double 和 char 类型的模板
ClassTemplate<int, double> obj1(2, 3.2, 'c');
cout << "obj1 values: " << endl;
obj1.printVar();
// 创建一个使用 int, double 和 bool 类型的模板
ClassTemplate<double, char, bool> obj2(8.2, 'a', false);
cout << "\nobj2 values: " << endl;
obj2.printVar();
return 0;
}
template <class T, class U, class V = char>
class ClassTemplate {
// code
};
这里创建了一个模板类,类名称为 ClassTemplate 并带有三个参数,其中一个参数带有默认值
class V = char表示v类型参数默认值为char类型,然后模板定义 3 个类型参数分别为成员变量的类型
内嵌模板类
模板可以被定义在类或类模板中,在这种情况下,成员模板。作为类的成员模板被称为嵌套类模板。属于函数的成员模板将在成员函数模板中讨论。
class Tut
{
template<class T>
struct Description
{
T m_val;
Description(T t) :m_val(t) {}
};
Description<int> mCourse;
Description<char> mTitle;
public:
Tut(int i, char c): mCourse(i), mTitle(c){}
void print()
{
std::cout << "test" << std::endl;
}
};