授课语音

C++ 类模板

1. 类模板概述

类模板是C++中一种强大的特性,允许我们定义可以处理不同类型数据的类。通过使用类模板,我们可以实现代码的复用,避免为每种数据类型编写重复的类。

1.1 优势

  • 代码复用:类模板允许我们创建通用的类,以适应多种数据类型。
  • 类型安全:模板类型在编译时被检查,确保类型安全。
  • 简化代码:减少了类的定义数量,便于维护和扩展。

2. 类模板的基本语法

类模板的基本语法如下:

template <typename T>
class ClassName {
public:
    T memberVariable; // 成员变量
    void memberFunction(T arg); // 成员函数
};

3. 代码案例:基本的类模板

以下代码展示了一个简单的类模板,用于实现一个通用的容器类。

#include <iostream>
using namespace std;

// 类模板定义
template <typename T>
class Container {
private:
    T element; // 存储元素

public:
    // 构造函数
    Container(T arg) : element(arg) {}

    // 获取元素
    T getElement() {
        return element;
    }
};

int main() {
    Container<int> intContainer(5); // 创建整型容器
    cout << "整型容器中的元素: " << intContainer.getElement() << endl; // 输出元素

    Container<string> stringContainer("Hello"); // 创建字符串容器
    cout << "字符串容器中的元素: " << stringContainer.getElement() << endl; // 输出元素

    return 0;
}

4. 类模板的特化

类模板的特化允许我们为特定类型提供不同的实现。

4.1 代码案例:类模板特化

以下示例为Container类模板提供了一个针对const char*类型的特化版本。

#include <iostream>
#include <cstring>
using namespace std;

// 类模板定义
template <typename T>
class Container {
private:
    T element; // 存储元素

public:
    Container(T arg) : element(arg) {}

    T getElement() {
        return element;
    }
};

// 特化版本
template <>
class Container<const char*> {
private:
    const char* element; // 存储字符串

public:
    Container(const char* arg) : element(arg) {}

    const char* getElement() {
        return element; // 返回字符串
    }

    int getLength() {
        return strlen(element); // 返回字符串长度
    }
};

int main() {
    Container<int> intContainer(10);
    cout << "整型容器中的元素: " << intContainer.getElement() << endl;

    Container<const char*> stringContainer("Hello, World!");
    cout << "字符串容器中的元素: " << stringContainer.getElement() << endl;
    cout << "字符串长度: " << stringContainer.getLength() << endl; // 输出字符串长度

    return 0;
}

5. 嵌套使用模板类

我们可以在类模板中使用其他类模板,这称为嵌套模板。

5.1 代码案例:嵌套模板类

以下示例展示了如何在类模板中使用另一个类模板。

#include <iostream>
using namespace std;

// 类模板
template <typename T>
class Holder {
private:
    T value; // 存储值

public:
    Holder(T v) : value(v) {}

    T getValue() {
        return value;
    }
};

// 嵌套模板类
template <typename T>
class Pair {
private:
    Holder<T> first; // 使用Holder类模板
    Holder<T> second;

public:
    Pair(T a, T b) : first(a), second(b) {}

    void display() {
        cout << "第一个元素: " << first.getValue() << ", 第二个元素: " << second.getValue() << endl;
    }
};

int main() {
    Pair<int> intPair(1, 2);
    intPair.display();

    return 0;
}

注释

  • 在这个示例中,Pair类模板中嵌套使用了Holder类模板,用于存储两个值。
  • 通过这种方式,可以将模板类嵌套使用,构建更复杂的数据结构。

6. 模板类与继承

模板类可以继承其他模板类或非模板类。

6.1 代码案例:模板类与继承

以下代码展示了模板类的继承。

#include <iostream>
using namespace std;

// 基础模板类
template <typename T>
class Base {
public:
    void show() {
        cout << "基础类" << endl;
    }
};

// 派生模板类
template <typename T>
class Derived : public Base<T> {
public:
    void display() {
        cout << "派生类" << endl;
    }
};

int main() {
    Derived<int> d;
    d.show(); // 调用基础类的方法
    d.display(); // 调用派生类的方法

    return 0;
}

注释

  • 在这个示例中,Derived类模板继承自Base类模板。
  • 通过这种方式,派生类可以访问基础类中的成员。

7. 模板类与函数

模板类可以与普通函数模板一起使用,也可以作为函数参数。

7.1 代码案例:模板类与函数

以下代码展示了如何将模板类用作函数参数。

#include <iostream>
using namespace std;

// 类模板
template <typename T>
class Box {
private:
    T item; // 存储物品

public:
    Box(T i) : item(i) {}

    T getItem() {
        return item;
    }
};

// 接受模板类作为参数的函数模板
template <typename T>
void displayBox(Box<T> box) {
    cout << "箱子中的物品: " << box.getItem() << endl;
}

int main() {
    Box<string> myBox("书籍");
    displayBox(myBox); // 调用函数模板

    return 0;
}

注释

  • 在这个示例中,displayBox函数模板接受一个Box类模板的对象作为参数。
  • 通过这种方式,我们可以将模板类作为参数传递给函数。

8. 模板类与友元

模板类也可以声明友元,以便访问私有成员。

8.1 代码案例:模板类与友元

以下代码展示了如何在模板类中使用友元。

#include <iostream>
using namespace std;

// 前向声明
template <typename T>
class FriendClass;

// 模板类
template <typename T>
class MyClass {
private:
    T value; // 存储值

public:
    MyClass(T v) : value(v) {}

    // 声明友元类
    friend class FriendClass<T>;
};

// 友元类
template <typename T>
class FriendClass {
public:
    void show(MyClass<T>& obj) {
        cout << "友元类访问私有值: " << obj.value << endl; // 访问私有成员
    }
};

int main() {
    MyClass<int> myObj(10);
    FriendClass<int> friendObj;
    friendObj.show(myObj); // 友元类访问私有成员

    return 0;
}

注释

  • 在这个示例中,FriendClass被声明为MyClass的友元。
  • 友元类能够访问私有成员,使得数据共享变得更加灵活。

9. 模板类的成员模板

模板类可以包含成员模板,允许在类的成员函数中使用模板。

9.1 代码案例:成员模板

以下示例展示了类模板中的成员模板。

#include <iostream>
using namespace std;

// 类模板
template <typename T>
class Calculator {
public:
    // 成员模板
    template <typename U>
    U add(U a, U b) {
        return a + b; // 返回两数之和
    }
};

int main() {
    Calculator<int> calc;
    cout << "整型相加: " << calc.add(10, 20) << endl; // 调用成员模板

    cout << "浮点数相加: " << calc.add(10.5, 20.3) << endl; // 调用成员模板

    return 0;
}

注释

  • 在这个示例中,Calculator类模板中的add函数是一个成员模板,可以接受不同类型的参数。
  • 这种设计使得类的功能更加灵活,能够处理多种数据类型的运算。

10. 总结

类模板是C++中一个强大且灵活的特性 ,能够提高代码的复用性和可维护性。通过今天的学习,我们深入了解了类模板的基本概念、定义方法、特化、嵌套使用、继承、友元、成员模板以及将模板类用作参数的相关内容。掌握这些知识能够帮助我们编写更加高效和通用的代码。

去1:1私密咨询

系列课程: