Skip to content

Latest commit

 

History

History
213 lines (148 loc) · 7.66 KB

C++032:C++模板初探:模板与重载.md

File metadata and controls

213 lines (148 loc) · 7.66 KB
title categories tags
C++ 模板与重载
开发
cpp
c++
cpp

C++ 模板与重载:从入门到进阶

在C++编程中,模板(Template)和重载(Overloading)是两个非常重要的概念。它们不仅能够提高代码的复用性,还能让代码更加灵活和高效。本文将从基础入手,逐步深入,结合代码示例,详细讲解C++中的模板与重载。

一、函数重载(Function Overloading)

1.1 什么是函数重载?

函数重载是指在同一个作用域内,可以定义多个同名函数,但它们的参数列表(参数的类型、数量或顺序)必须不同。编译器会根据调用时传入的参数来决定调用哪个函数。

1.2 为什么需要函数重载?

函数重载的主要目的是为了简化代码,避免为相似的功能定义多个不同的函数名。例如,你可能需要一个函数来处理整数,另一个函数来处理浮点数,但它们的逻辑是相似的。通过重载,你可以用同一个函数名来处理不同类型的数据。

1.3 代码示例

#include <iostream>

// 重载函数:计算两个整数的和
int add(int a, int b) {
    return a + b;
}

// 重载函数:计算两个浮点数的和
double add(double a, double b) {
    return a + b;
}

// 重载函数:计算三个整数的和
int add(int a, int b, int c) {
    return a + b + c;
}

int main() {
    std::cout << "两个整数的和: " << add(1, 2) << std::endl;       // 调用第一个add函数
    std::cout << "两个浮点数的和: " << add(1.5, 2.5) << std::endl; // 调用第二个add函数
    std::cout << "三个整数的和: " << add(1, 2, 3) << std::endl;    // 调用第三个add函数
    return 0;
}

1.4 代码分析

  • 函数签名:在C++中,函数的签名由函数名和参数列表组成。即使返回类型不同,只要参数列表相同,编译器也会认为它们是同一个函数。
  • 调用匹配:编译器会根据调用时传入的参数类型和数量,自动选择最匹配的重载函数。
  • 注意事项:重载函数不能仅通过返回类型来区分,必须通过参数列表的不同来区分。

二、模板(Template)

2.1 什么是模板?

模板是C++中的一种泛型编程机制,允许你编写与类型无关的代码。通过模板,你可以定义一个通用的函数或类,然后在实际使用时,编译器会根据传入的类型生成具体的代码。

2.2 为什么需要模板?

模板的主要目的是为了提高代码的复用性。通过模板,你可以编写一次代码,然后适用于多种不同的数据类型。例如,你可以编写一个通用的排序函数,而不需要为每种数据类型单独编写一个排序函数。

2.3 函数模板(Function Template)

2.3.1 代码示例

#include <iostream>

// 定义一个函数模板,用于计算两个数的和
template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << "两个整数的和: " << add(1, 2) << std::endl;       // 调用add<int>
    std::cout << "两个浮点数的和: " << add(1.5, 2.5) << std::endl; // 调用add<double>
    return 0;
}

2.3.2 代码分析

  • 模板定义template <typename T> 表示定义一个模板,T 是一个占位符,表示任意类型。
  • 模板实例化:当调用 add(1, 2) 时,编译器会自动推导出 Tint,并生成一个具体的 add<int> 函数。
  • 类型推导:编译器会根据传入的参数类型自动推导出模板参数 T 的类型。

2.4 类模板(Class Template)

2.4.1 代码示例

#include <iostream>

// 定义一个类模板,用于存储两个相同类型的值
template <typename T>
class Pair {
public:
    T first;
    T second;

    Pair(T first, T second) : first(first), second(second) {}

    T getSum() {
        return first + second;
    }
};

int main() {
    Pair<int> intPair(1, 2);       // 实例化一个Pair<int>对象
    std::cout << "整数对的和: " << intPair.getSum() << std::endl;

    Pair<double> doublePair(1.5, 2.5); // 实例化一个Pair<double>对象
    std::cout << "浮点数对的和: " << doublePair.getSum() << std::endl;

    return 0;
}

2.4.2 代码分析

  • 类模板定义template <typename T> 表示定义一个类模板,T 是一个占位符,表示任意类型。
  • 类模板实例化Pair<int>Pair<double> 是类模板的实例化,编译器会根据模板生成具体的类。
  • 成员函数:类模板中的成员函数也可以是模板函数,编译器会根据实例化的类型生成具体的成员函数。

三、模板与重载的结合

3.1 模板重载

模板也可以进行重载,即可以定义多个同名的模板函数或类模板,但它们的模板参数列表必须不同。

3.1.1 代码示例

#include <iostream>

// 第一个模板函数:计算两个数的和
template <typename T>
T add(T a, T b) {
    return a + b;
}

// 第二个模板函数:计算三个数的和
template <typename T>
T add(T a, T b, T c) {
    return a + b + c;
}

int main() {
    std::cout << "两个整数的和: " << add(1, 2) << std::endl;       // 调用第一个add模板函数
    std::cout << "三个整数的和: " << add(1, 2, 3) << std::endl;    // 调用第二个add模板函数
    return 0;
}

3.1.2 代码分析

  • 模板重载:虽然两个模板函数的名字相同,但它们的模板参数列表不同(一个是两个参数,一个是三个参数),因此它们是不同的模板函数。
  • 调用匹配:编译器会根据调用时传入的参数数量,自动选择最匹配的模板函数。

3.2 模板与非模板的混合重载

你还可以将模板函数与非模板函数进行重载。在这种情况下,非模板函数会被优先调用,除非模板函数更匹配。

3.2.1 代码示例

#include <iostream>

// 非模板函数:计算两个整数的和
int add(int a, int b) {
    return a + b;
}

// 模板函数:计算两个数的和
template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << "两个整数的和: " << add(1, 2) << std::endl;       // 调用非模板函数
    std::cout << "两个浮点数的和: " << add(1.5, 2.5) << std::endl; // 调用模板函数
    return 0;
}

3.2.2 代码分析

  • 非模板函数优先:当调用 add(1, 2) 时,编译器会优先选择非模板函数,因为非模板函数是更具体的实现。
  • 模板函数匹配:当调用 add(1.5, 2.5) 时,由于没有非模板函数可以匹配,编译器会选择模板函数。

四、总结

  • 函数重载:通过函数重载,你可以在同一个作用域内定义多个同名函数,但它们的参数列表必须不同。重载函数可以根据传入的参数类型和数量,自动选择最匹配的函数。
  • 模板:模板是C++中的一种泛型编程机制,允许你编写与类型无关的代码。通过模板,你可以定义通用的函数或类,然后在实际使用时,编译器会根据传入的类型生成具体的代码。
  • 模板与重载的结合:模板和重载可以结合使用,以实现更灵活和高效的代码。模板重载允许你定义多个同名的模板函数或类模板,而非模板函数与模板函数的混合重载则提供了更具体的实现。

文章合集:chongzicbo/ReadWriteThink: 博学而笃志,切问而近思 (github.com)

个人博客:程博仕

微信公众号:

微信公众号