MST

星途 面试题库

面试题:C++自定义RAII类的实现与注意事项

请编写一个C++类,使用RAII机制来管理动态分配的内存(如`new`分配的数组)。在类中需要包含构造函数、析构函数、拷贝构造函数和赋值运算符重载,并说明在实现这些函数时需要注意哪些问题以确保RAII机制的正确运作。
23.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>
#include <cstring>

class MyRAII {
private:
    int* data;
    size_t size;

public:
    // 构造函数
    MyRAII(size_t n) : size(n) {
        data = new int[size];
        std::memset(data, 0, size * sizeof(int));
    }

    // 析构函数
    ~MyRAII() {
        delete[] data;
    }

    // 拷贝构造函数
    MyRAII(const MyRAII& other) : size(other.size) {
        data = new int[size];
        std::memcpy(data, other.data, size * sizeof(int));
    }

    // 赋值运算符重载
    MyRAII& operator=(const MyRAII& other) {
        if (this != &other) {
            delete[] data;
            size = other.size;
            data = new int[size];
            std::memcpy(data, other.data, size * sizeof(int));
        }
        return *this;
    }
};

实现这些函数时的注意事项

  1. 构造函数
    • 确保成功分配内存,如果分配失败(如new抛出异常),对象不应进入无效状态。在上述代码中,使用new分配内存,若失败会抛出std::bad_alloc异常。
    • 初始化对象的成员变量,为对象设置一个有效的初始状态。例如上述代码中初始化了size和分配并初始化了data数组。
  2. 析构函数
    • 必须释放构造函数中分配的资源,在上述代码中,通过delete[] data释放动态分配的数组。析构函数不能抛出异常,否则可能导致未定义行为。
  3. 拷贝构造函数
    • 执行深拷贝,即创建新的资源副本,而不是共享资源。如上述代码中为data重新分配内存并复制数据。
    • 确保新对象的状态与原对象一致,例如size成员变量也需要正确拷贝。
  4. 赋值运算符重载
    • 检查自赋值,即this != &other,防止不必要的资源释放和重新分配。
    • 释放对象当前拥有的资源(如delete[] data),然后进行深拷贝,为对象分配新的资源并复制数据。
    • 返回*this以支持链式赋值,如a = b = c