MST
星途 面试题库

面试题:C++赋值运算符重载与异常安全性

设计一个C++类`ComplexData`,该类包含多个不同类型的成员变量,其中部分成员变量涉及动态资源分配(如动态数组、智能指针等)。实现该类的赋值运算符重载函数,要求满足异常安全性,即如果在赋值过程中抛出异常,对象的状态应保持一致且不发生内存泄漏。请详细说明你的设计思路,并给出完整的代码实现。
50.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 考虑成员变量:对于包含动态资源分配的成员变量(如动态数组、智能指针),在赋值运算符重载函数中需要正确处理资源的释放与重新分配。
  2. 异常安全性:采用“拷贝并交换”(copy-and-swap)技术来实现异常安全。这种技术先创建一个临时对象,将其成员变量与目标对象的成员变量交换,这样如果在创建临时对象或交换过程中抛出异常,原对象的状态不会改变,不会发生内存泄漏。
  3. 自赋值检查:在赋值运算符重载函数开始时,先检查是否为自赋值,避免不必要的操作。

代码实现

#include <iostream>
#include <memory>

class ComplexData {
private:
    int* dynamicArray;
    std::unique_ptr<int> smartPtr;
    int regularVariable;

public:
    ComplexData() : dynamicArray(nullptr), smartPtr(nullptr), regularVariable(0) {}

    ComplexData(int size, int value, int regValue)
        : regularVariable(regValue) {
        dynamicArray = new int[size];
        for (int i = 0; i < size; ++i) {
            dynamicArray[i] = value;
        }
        smartPtr = std::make_unique<int>(value);
    }

    ~ComplexData() {
        delete[] dynamicArray;
    }

    // 拷贝构造函数
    ComplexData(const ComplexData& other)
        : regularVariable(other.regularVariable) {
        if (other.dynamicArray) {
            int size = 0;
            while (other.dynamicArray[size] != 0) {
                ++size;
            }
            dynamicArray = new int[size];
            for (int i = 0; i < size; ++i) {
                dynamicArray[i] = other.dynamicArray[i];
            }
        } else {
            dynamicArray = nullptr;
        }
        smartPtr = std::make_unique<int>(*other.smartPtr);
    }

    // 赋值运算符重载
    ComplexData& operator=(ComplexData other) {
        // 自赋值检查
        if (this == &other) {
            return *this;
        }
        // 交换成员变量
        std::swap(dynamicArray, other.dynamicArray);
        std::swap(smartPtr, other.smartPtr);
        std::swap(regularVariable, other.regularVariable);
        return *this;
    }

    void print() const {
        if (dynamicArray) {
            std::cout << "Dynamic Array: ";
            for (int i = 0; dynamicArray[i] != 0; ++i) {
                std::cout << dynamicArray[i] << " ";
            }
            std::cout << std::endl;
        }
        std::cout << "Smart Ptr: " << *smartPtr << std::endl;
        std::cout << "Regular Variable: " << regularVariable << std::endl;
    }
};

int main() {
    ComplexData obj1(3, 10, 20);
    ComplexData obj2;
    obj2 = obj1;
    obj1.print();
    obj2.print();
    return 0;
}