瑞星 发表于 2024-10-20 15:04:25

C++之美:代码整洁、安全又跑得快的30个要诀(好书保举)

在编程领域,C++ 以其高效性和机动性著称,但同时也因其复杂性和易堕落性而闻名。如何写出既整洁、又安全且高效的 C++ 代码,是每个 C++ 开辟者都必要思考的问题。《C++之美:代码整洁、安全又跑得快的30个要诀》这本书为我们提供了宝贵的指导。本文将基于这本书的核心内容,分享此中的精华,帮助各人提拔 C++ 编程程度。
前言

C++ 是一门汗青久长且功能强大的编程语言,广泛应用于系统开辟、游戏引擎、高性能盘算等领域。然而,C++ 的复杂性也给开辟者带来了不少挑战。本书通过总结和提炼了30个实用的编程要诀,帮助读者写出既整洁、又安全且高效的 C++ 代码。
《C++之美:代码轻便、安全又跑得快的30个要诀》从《C++核心准则》(C++ Core Guidelines)中经心挑选了30条准则进行过细、深入的讲解。内容涵盖C++语言最重要的方面,如范例系统、面向对象、模板和元编程、错误处置惩罚、程序性能、常量性等,其间又恰如其分地穿插了编码风格、设计模式等主题。书中搜集了作者数十年职业生涯的经验和一些有趣的示例,除了深刻的见解,行文也充满了意见意义性。作者试图通过这种突出重点、以点带面的方式帮助读者了解并学习《C++核心准则》,进而更深入地把握C++这门编程语言,特别是它的“现代”形态。本书适合各种程度的C++开辟者阅读。

https://i-blog.csdnimg.cn/direct/6a1bf4577cc84b40ae1a0ab6a0c8dd9a.png
作者简介

J. Guy Davidson于1980年通过Acorn Atom首次接触编程。他青少年期间的大部分时间都在各种家用电脑上编写游戏。后来,他从苏塞克斯大学得到了数学学位,开始涉足戏剧,还在一个灵魂乐队中担任键盘手。20世纪90年代初,他决定编写演示程序,并于1997年开始在Codemasters的伦敦办公室工作,今后进入游戏行业。1999年,Davidson加入了Creative Assembly,如今是那里的工程实践主管。他重要负责《全面战争》(Total War)系列游戏的工作,整理早期的游戏目次,以及提拔工程团队成员的编程程度。他是IGGI咨询委员会、BSI C++小组和ISO C++委员会的委员,还是ACCU(Association of C/C++ Users,C/C++用户协会)负责C++标准相干事件的成员,并在ACCU的编程委员会任职。
核心要诀概览

本书围绕着“整洁、安全、高效”三个核心主题,详细介绍了30个编程要诀。
以下是此中的一些关键点:
1.整洁

代码风格同一:遵循一致的代码风格规范,如定名规则、缩进、解释等。
轻便表达:只管利用轻便的表达式和函数,避免冗余代码。
模块化设计:将代码分解成可重用的模块,提高代码的可维护性。
最小作用域:变量应在最晚可能的时间声明,在最早不被利用后销毁,镌汰潜伏的副作用和内存占用。
函数单一职责:每个函数应该只有一个明白的任务,如许做不仅使得代码易于理解,也便于测试和维护。
2.安全

内存安全:避免利用原始指针,只管利用智能指针(如 std::unique_ptr 和 std::shared_ptr)。
资源管理:遵循 RAII(Resource Acquisition Is Initialization)原则,确保资源的正确释放。(如文件句柄、数据库毗连)在对象生命周期结束时自动释放。
非常安全:编写非常安全的代码,确保在非常情况下也能正确释放资源。确保资源管理和状态保持一致。
3.高效

性能优化:理解 C++ 标准库的性能特性,公道利用标准库函数。
编译优化:利用现代编译器的优化选项,提高代码的执行服从。
并发编程:公道利用多线程和并发编程技能,提高程序的并发性能。
具体要诀详解

1. 代码风格同一

定名规范:接纳一致的定名规范,如 camelCase 或 snake_case。
缩进和空格:利用一致的缩进和空格,提高代码的可读性。
解释:为重要的代码段添加解释,说明代码的功能和意图。
确保不同模块和函数之间的风格和设计一致,可以增强团队的协作性,降低维护本钱。
2. 轻便表达

利用范围for循环:利用 for (auto& item : container) 来遍历容器,轻便且不易堕落。
    std::vector<int> numbers = {1, 2, 3};
    for (auto& num : numbers) {
      std::cout << num << " ";
    }
    利用lambda表达式:利用 lambda 表达式简化回调函数的定义。
std::sort(numbers.begin(), numbers.end(), [](int a, int b) { return a > b; });
    避免冗余代码:只管复用已有代码,避免重复编写相同的逻辑。
    template<typename T>
    void print(T value) {
      std::cout << value << std::endl;
    }
    3. 模块化设计

分离接口和实现:将接口和实现分离,提高代码的可维护性和可扩展性。
利用头文件和源文件:将类的声明放在头文件中,实现放在源文件中。
公道构造代码布局:按照功能模块构造代码,提高代码的可读性和可维护性。
限订定名空间:只管避免利用全局定名空间,限制变量和函数的作用域,可以镌汰定名辩说的几率。
    src/
    ├── my_class.h
    ├── my_class.cpp
    └── utils.h
        // my_class.h
    class MyClass {
    public:
      void doSomething();
    };

    // my_class.cpp
    #include "my_class.h"

    void MyClass::doSomething() {
      // 实现细节
    }
    接口设计:清晰定义接口,隔离实现细节,促进模块间的松耦合。
模板编程:通过泛型编程实现范例无关的代码复用,提拔代码的通用性和机动性。 
4. 内存安全

利用智能指针:利用 std::unique_ptr 和 std::shared_ptr 管理动态分配的内存,避免内存走漏。
std::unique_ptr<MyClass> ptr(new MyClass());
   
std::unique_ptr<MyClass> ptr = std::make_unique<MyClass>();
MyClass* rawPtr = ptr.get();// 使用智能指针获取原始指针
    避免野指针:确保指针始终指向有效的对象,避免利用已删除的对象。
利用RAII:通过 RAII 技能管理资源,确保资源在对象生命周期结束时自动释放。
    class Resource {
    public:
      Resource() { /* 初始化资源 */ }
      ~Resource() { /* 释放资源 */ }
    };

    void someFunction() {
      Resource resource;// RAII
    }
    空指针和边界检查:在利用指针或数组时,务必进行空指针和边界检查,以避免程序瓦解。 
5. 资源管理

利用RAII:通过 RAII 技能管理资源,确保资源在对象生命周期结束时自动释放。
避免资源竞争:公道利用锁机制,避免资源竞争导致的死锁或竞态条件。
    std::mutex mutex;

    void someFunction() {
      std::lock_guard<std::mutex> lock(mutex);
      // 执行临界区代码
    }
    资源池技能:利用资源池技能管理大量相似资源,提高资源的利用率。
    class ResourcePool {
    public:
      Resource getResource() {
            std::lock_guard<std::mutex> lock(mutex);
            if (!available.empty()) {
                Resource res = available.front();
                available.pop();
                return res;
            }
            return Resource();
      }

      void releaseResource(Resource res) {
            std::lock_guard<std::mutex> lock(mutex);
            available.push(res);
      }

    private:
      std::queue<Resource> available;
      std::mutex mutex;
    };
    6. 非常安全

非常安全的构造函数:确保构造函数在抛出非常时能够正确释放资源。
    class MyClass {
    public:
      MyClass() {
            try {
                // 初始化资源
            } catch (...) {
                // 清理资源
                throw;
            }
      }
    };
    非常安全的析构函数:确保析构函数在抛出非常时能够正确释放资源。
    class MyClass {
    public:
      ~MyClass() {
            // 释放资源
      }
    };
    非常安全的成员函数:确保成员函数在抛出非常时能够正确释放资源。
    class MyClass {
    public:
      void someFunction() {
            try {
                // 执行操作
            } catch (...) {
                // 清理资源
                throw;
            }
      }
    };
    利用代码分析工具(如Clang-Tidy)可以帮助我们辨认潜伏问题,提高代码质量。 
7. 性能优化

理解标准库性能:了解标准库函数的内部实现,公道利用标准库函数。
    std::vector<int> numbers = {1, 2, 3};
    std::sort(numbers.begin(), numbers.end());
    编译器优化:利用编译器的优化选项(如 -O3),提高代码的执行服从。
避免不必要的复制:利用移动语义(move semantics)镌汰不必要的复制。
    MyClass moveFunc(MyClass&& obj) {
      return std::move(obj);
    }
    8. 并发编程

利用线程库:利用 std::thread 和 std::mutex 实现多线程编程。
利用原子操作:利用 std::atomic 范例保证数据的一致性。
公道利用线程池:利用线程池技能管理线程资源,提高并发性能。
对于轻量级同步,优先思量利用std::atomic;对于复杂场景,选用适当的锁机制,如std::mutex或更高级的锁。
避免数据竞争:设计线程安全的数据布局,确保多线程访问数据时的一致性和完备性。
在多线程编程中,注意数据共享和线程安全的问题。利用C++11的std::mutex等同步机制可以有效防止数据竞争。
总结

通过学习《C++之美:代码整洁、安全又跑得快的30个要诀》,我们可以更好地理解和把握 C++ 的核心编程本事。无论是初学者还是经验丰富的开辟者,都可以从中受益匪浅。希望本文的分享能帮助各人提拔 C++ 编程程度,写出更加良好和可靠的代码。
写在末了

末了,保举下笔者的业余开源app影视项目“爱影家”,保举分享给与我一样喜欢观影的朋侪。
开源地址:爱影家app开源项目介绍及源码
https://gitee.com/yyz116/imovie 其他资源

https://book.douban.com/subject/36962341/

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: C++之美:代码整洁、安全又跑得快的30个要诀(好书保举)