阅读 246
C++模版:类模版初探

C++模版:类模版初探

在定义类的时候,继承和组合可以满足大部分需求。但是对于某些场景,比如用来储存对象的容器类,针对不同的储存对象类型,容器类都需要提供相同的代码实现。如果使用类模版,可以将储存对象类型作为参数传给容器类,这样就可以使用一套容器类代码。

类模版语法

类模版的语法如下,<>包起来的是模版参数列表,可以有多个参数,用逗号分隔。

template <typename T>
类声明
复制代码

template :关键字,表示定义模板

typename :关键字,表示一个类型参数

T :变量名,其值代表一个类型。在类中使用。该变量名一般用大写表示。

成员函数,也需要以相同的模板声明开头,并且类限定符也要包含模版参数。

template <typename T>
void ClassName<T>::func() {

}
复制代码

定义类模版

定义一个容器类Stack

template <typename T>
class Stack {
private:
    T items[10];
    int top;
    
public:
    Stack();
    bool isEmpty();
};

template <typename T>
Stack<T>::Stack() {
    top = 0;
}

template <typename T>
bool Stack<T>::isEmpty() {
    return top == 0;
}
复制代码

使用类模版

有2种使用类模版的方式,编译器会生成一个特定版本的类,这叫做实例化。

  • 指定模版的类型,并且用它定义一个或者多个对象。如果没有生成对象,类模板不会实例化。这叫做隐式实例化。
  • 使用template和类型来定义一个类,不管有没有生成对象,类模版都会实例化。这叫做显示实例化。

示例如下:

template class Stack<std::string>;      // 显示实例化
void test6() {
    Stack<int> s1;      // 隐式实例化Stack<int>
    if (s1.isEmpty()) {
        std::cout << "Stack<int> s1 is empty: " << std::endl;
    }
    
    Stack<double> *s2;      // 没有实例化,因为没有生成对象
    s2 = new Stack<double>();   // 实例化Stack<double>
    delete s2;
}
复制代码

类模版的声明和实现写在头文件

一般情况下,在hpp文件声明一个类的成员函数或者成员数据,在cpp文件实现成员函数。

同样地,在array.hpp声明一个类模版:

#ifndef array_hpp
#define array_hpp

template <typename T>
class Array {
private:
    int count;
    
public:
    Array();
};

#endif
复制代码

array.cpp定义成员函数模版:

template <typename T>
Array<T>::Array() {
    count = 0;
}
复制代码

main.cpp使用该类模版,编译器应该生成int类型的Array类,并且使用构造函数创建一个对象a

#include <iostream>
#include "array.hpp"

int main(int argc, const char * argv[]) {
    Array<int> a;
    return 0;
}
复制代码

但是,编译这些代码,会发生错误:

Undefined symbol: Array<int>::Array()
复制代码

这是因为类模版和成员函数模版,并不是类和成员函数。前者是一种指令,告诉编译器如何生成后者。

类模版以及成员函数模版,不能分开编译,一般是将他们都放到hpp文件。代码就可以正常运行。

#ifndef array_hpp
#define array_hpp

template <typename T>
class Array {
private:
    int count;
    
public:
    Array();
};

template <typename T>
Array<T>::Array() {
    count = 0;
}

#endif
复制代码

阅读原文,关注[空与一],获取更多C++知识。

文章分类
开发工具
文章标签