Posts Modern-C++_编程范式
Post
Cancel

Modern-C++_编程范式

前置背景

C++支持多范式编程语言,允许开发者根据具体需求选择最佳的设计方法,具体包含以下五种:

编程范式特点应用场景
面向过程编程基于函数和步骤,操作全局变量,简单直接。小型程序、脚本型任务
面向对象编程封装数据和行为,支持继承和多态,适合复杂系统设计。游戏开发、GUI应用、企业级系统
泛型编程类型无关的通用代码设计,提高代码复用性和性能。数据结构、算法库(如STL)
函数式编程纯函数和高阶函数,避免状态和副作用。并发编程、大数据处理、分布式系统
元编程编译时计算和优化,减少运行时开销,提高性能。库设计、性能优化(如Eigen、Boost)

面向过程编程(Procedural Programming)

核心思想:程序由一系列函数和步骤组成,按照一定的顺序执行。特性:

  • 强调函数和过程。

  • 使用全局变量和参数传递共享数据。

  • 易于实现和理解,但随着程序规模增大,可能导致代码难以维护。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>

// 全局变量
std::string global_str = "Demo: ";

void greet(const std::string& message) {
    std::cout << global_str << message << std::endl;
}

int main() {
    std::string message = "你好";
    greet(message);
    return 0;
}

面向对象编程(Object-Oriented Programming)

C++新特性增强了类的定义和操作能力,使面向对象编程更加灵活。特性:

  • 显式虚函数覆盖(override、final):防止错误的函数覆盖。

  • 默认和删除的函数(=default, =delete):控制特殊成员函数的生成。

  • 继承构造函数:简化子类的构造。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>

class Base {
public:
    virtual void show() const = 0;
    virtual ~Base() = default; // 默认析构函数: 编译器构造
    Base& operator=(const Base&) = delete; // 禁用赋值运算符
};

class Derived final : public Base { // final: Derived类不可继承
public:
    void show() const override { // 显式覆盖
        std::cout << "Derived class" << std::endl;
    }
};

int main() {
    Base* obj = new Derived();
    obj->show(); // 输出: Derived class
    delete obj;
    return 0;
}

泛型编程(Generic Programming)

模板是C++泛型编程的核心,C++11起引入的模板新特性使模板编程更加强大。特性:

  • 变参模板(Variadic Templates):支持任意数量的模板参数。

  • 模板别名(Template Alias):简化模板使用。

  • 自动推导(auto, decltype):增强类型推导。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

// 特化模板
template <>
void print<std::string value> {
    std::cout << "String: " << value << std::endl;
}

// 递归展开的变参模板
template<typename T>
void print(T value) {
    std::cout << value << std::endl;
}

template<typename T, typename... Args> // 类型参数包,可以匹配任意数量和类型的模板参数
void print(T value, Args... args) {
    std::cout << value << " ";
    std::cout << ... << args << std::endl; // C++17
    print(args...); // C++11: 递归调用
}

int main() {
    print(1, 2.5, "Hello", 'A'); // 输出: 1 2.5 Hello A
    return 0;
}

函数式编程(Functional Programming)

C++11及更高版本通过引入 lambda 表达式和 std::function 等功能,为函数式编程提供了支持。特性:

  • Lambda表达式

    允许定义匿名函数。

1
2
3
4
5
6
7
8
9
10
11
// [捕获列表](参数列表) mutable -> 返回类型 { 函数体 }
// 样例:
//     1. 混合捕获所有变量,除了var按照引用捕获
//     2. mutable表示支持函数内部修改捕获的非引用值,外部不受影响
//     3. double指定函数返回类型
#include <iostream>

int x = 5;
auto divide = [=, &var](int a, int b) mutable -> double {return (double)a / b; };
std::cout << divide(5, 2) << std::endl;

  • std::function:实现函数对象的通用存储。

  • std::bind:绑定函数参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};

    // 使用Lambda表达式
    auto square = [](int x) { return x * x; };
    for (int num : nums) {
        std::cout << square(num) << " ";
    }
    std::cout << std::endl;

    // 使用std::function存储Lambda
    std::function<int(int)> multiply_by_2 = [](int x) { return x * 2; };
    std::cout << multiply_by_2(10) << std::endl;

    // 使用std::bind
    auto add = [](int a, int b) { return a + b; };
    auto add_five = std::bind(add, 5, std::placeholders::_1);
    std::cout << add_five(3) << std::endl;

    return 0;
}

元编程(Meta Programming)

元编程是 C++ 的高级特性,广泛用于标准库和现代库的实现中(如 Boost、Eigen),在提升性能、灵活性和类型安全性方面具有重要意义。通过constexpr、type_traits等新特性,C++支持编译时计算和类型操作。特性:

  • constexpr:允许在编译时计算。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    #include <iostream>
    #include <type_traits>
        
    // constexpr函数
    constexpr int factorial(int n) {
        return (n <= 1) ? 1 : n * factorial(n - 1);
    }
        
    int main() {
        constexpr int result = factorial(5); // 编译时计算
        std::cout << "Factorial of 5 is " << result << std::endl;
        
        // 使用type_traits
        std::cout << std::boolalpha;
        std::cout << "Is int integral? " << std::is_integral<int>::value << std::endl;
        std::cout << "Is float integral? " << std::is_integral<float>::value << std::endl;
        
        return 0;
    }
    
  • type_traits:提供类型特征检查。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    #include <iostream>
    #include <type_traits>
        
    // 检查类型是否为整数:std::is_integral
    int main() {
        std::cout << std::boolalpha;
        std::cout << "Is int an integral type? " << std::is_integral<int>::value << std::endl; // true
        std::cout << "Is float an integral type? " << std::is_integral<float>::value << std::endl; // false
        return 0;
    }
    
  • if constexpr:编译时条件分支。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    
    #include <iostream>
    #include <type_traits>
        
    // C++11: 仅对整数类型有效
    template <typename T>
    typename std::enable_if<std::is_integral<T>::value, void>::type
    print(T value) {
        std::cout << "Integral: " << value << std::endl;
    }
        
    // C++11: 仅对浮点数类型有效
    template <typename T>
    typename std::enable_if<std::is_floating_point<T>::value, void>::type
    print(T value) {
        std::cout << "Floating Point: " << value << std::endl;
    }
        
    // C++17
    template <typename T>
    void print(T value) {
        if constexpr (std::is_integral<T>::value) {
            std::cout << "Integral: " << value << std::endl;
        } else if constexpr (std::is_floating_point<T>::value) {
            std::cout << "Floating Point: " << value << std::endl;
        } else {
            std::cout << "Unknown type!" << std::endl;
        }
    }
        
    int main() {
        print(10);    // 输出: Integral: 10
        print(3.14);  // 输出: Floating Point: 3.14
        return 0;
    }
    
  • 类型列表和操作

    通过递归模板和 std::conditional 操作类型列表。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    #include <iostream>
    #include <type_traits>
        
    // 比较两个类型的大小
    template <typename T1, typename T2>
    struct LargerType {
        using type = typename std::conditional<(sizeof(T1) > sizeof(T2)), T1, T2>::type;
    };
        
    // 递归获取最大类型
    template <typename T1, typename T2, typename... Rest>
    struct LargestType {
        using type = typename LargestType<typename LargerType<T1, T2>::type, Rest...>::type;
    };
        
    // 基本情况
    template <typename T>
    struct LargestType<T> {
        using type = T;
    };
        
    int main() {
        using Largest = LargestType<int, double, char>::type;
        std::cout << "Largest type size: " << sizeof(Largest) << std::endl; // 输出: 8 (double)
        return 0;
    }
    
  • 静态多态(CRTP-Curiously Recurring Template Pattern)

    实现基于模板的接口继承,通过 CRTP 模式实现静态多态,避免了虚函数的运行时开销。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

// CRTP 基类
template <typename Derived>
class Base {
public:
    void interface() {
        static_cast<Derived*>(this)->implementation();
    }
};

// 派生类
class Derived : public Base<Derived> {
public:
    void implementation() {
        std::cout << "Derived implementation!" << std::endl;
    }
};

int main() {
    Derived d;
    d.interface(); // 输出: Derived implementation!
    return 0;
}
  • 编译时断言

    基于 static_assert 等在编译时验证代码条件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    #include <iostream>
        
    template <typename T>
    void checkType() {
        static_assert(std::is_integral<T>::value, "Type must be integral!");
        std::cout << "Type is integral." << std::endl;
    }
        
    int main() {
        checkType<int>();    // 输出: Type is integral.
        // checkType<double>(); // 编译错误: Type must be integral!
        return 0;
    }
    
This post is licensed under CC BY 4.0 by the author.

Modern-C++_语言基础

Modern-C++_STL_容器