浅析C++中RAII

2024-07-18 13:23:44 浏览数 (2)

在C 编程中,RAII(Resource Acquisition Is Initialization,资源获取即初始化)是一种重要的编程范式,被广泛应用于管理资源的生命周期。这种技术通过在对象的构造函数中获取资源,而在析构函数中以获取顺序的逆序释放资源,从而确保资源在对象生命周期内得到正确管理。

定义

RAII是一种C 编程中的编程范式,它将资源的生命周期与对象的生命周期绑定在一起。资源可以是分配的堆内存、执行线程、打开的套接字、打开的文件、锁定的互斥体、磁盘空间、数据库连接等——任何存在于受限供给的事物,而对象可以是任何具有生命周期的实体。通过RAII,资源的获取和释放是自动进行的,从而避免了资源泄漏和内存泄漏等问题。

基本思想

RAII的基本思想:在对象的构造函数中获取资源,并在析构函数中释放资源。这样一来,当对象被创建时,资源就被正确地获取了;当对象被销毁时,资源就被自动释放了。这种自动管理资源的机制确保了资源的正确使用,同时也提高了代码的可靠性和安全性。

使用场景

RAII广泛应用于各种场景,特别是在需要管理资源的情况下。一些常见的应用场景包括:

  • 内存管理:通过RAII可以方便地管理动态分配的内存,避免内存泄漏和空悬指针等问题。
  • 文件管理:通过RAII可以方便地管理文件句柄,确保文件在使用完毕后被正确关闭。
  • 锁管理:通过RAII可以方便地管理互斥锁、读写锁等,确保锁在使用完毕后被正确释放。

C 标准库中的许多类都使用了RAII思想来管理资源,其中包括智能指针、文件流、互斥锁等。例如,

  • std::unique_ptr 和 std::shared_ptr 分别用于管理动态分配的内存,它们在构造时获取了资源(内存),在析构时自动释放资源。
  • std::fstream 用于文件的输入输出操作,它在构造时打开文件,在析构时关闭文件,确保文件资源的正确释放。
  • std::lock_guard、std::unique_lock、std::shared_lock等锁类型在构造时获取锁,在析构时释放锁,确保锁的正确管理,避免死锁等问题。
  • std::jthrad自汇合线程,在构造生成新线程,在析构时自动join线程,确保线程正常退出,避免崩溃

项目中应用。

在实际项目中,RAII也是大有用武之地的,比如之前在这才是面试官想听到的答案,C er必须得看看讲过的统计函数耗时的例子,函数内部有100个return,如何统计耗时。如下代码

代码语言:javascript复制
#include <iostream>  
#include <chrono>  
  
class Timer {  
public:  
    Timer(const std::string& functionName) : start_(std::chrono::high_resolution_clock::now()), functionName_(functionName) {}  
    ~Timer() {  
        auto end = std::chrono::high_resolution_clock::now();  
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start_).count();  
        std::cout << functionName_ << " took " << duration << " ms." << std::endl;  
    }  
  
private:  
    std::chrono::time_point<std::chrono::high_resolution_clock> start_;  
    const std::string functionName_;  
};  
  
// 示例函数,用于演示Timer类的使用  
void someFunction() {  
    Timer timer("someFunction");  
    // 在这里执行一些操作  
    // ...  
    // 无需显式调用任何计时结束的函数,因为析构函数会自动处理  
}  
  
int using_some_function() {  
    someFunction(); // 当someFunction返回时,Timer的析构函数会被调用,输出耗时  
    return 0;  
}

结论

RAII是C 编程中的一种重要的编程范式,通过将资源的生命周期与对象的生命周期绑定在一起,确保了资源的正确管理和释放。在实际项目中,RAII被广泛应用于各种场景,帮助我们编写出更加健壮、可靠的代码。

0 人点赞