MST
星途 面试题库

面试题:C++ 移动语义与资源管理

假设有一个类`ResourceHolder`用于管理动态分配的内存资源(例如一个`int`数组),请详细说明如何利用移动语义在对象之间高效转移资源,避免不必要的内存拷贝。并编写完整的`ResourceHolder`类,包含构造函数、析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数和移动赋值运算符。
42.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

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

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

public:
    // 构造函数
    ResourceHolder(size_t s) : size(s) {
        data = new int[s];
        std::cout << "Constructor: Allocated memory for " << size << " integers." << std::endl;
    }

    // 析构函数
    ~ResourceHolder() {
        if (data) {
            delete[] data;
            std::cout << "Destructor: Freed memory." << std::endl;
        }
    }

    // 拷贝构造函数
    ResourceHolder(const ResourceHolder& other) : size(other.size) {
        data = new int[size];
        for (size_t i = 0; i < size; ++i) {
            data[i] = other.data[i];
        }
        std::cout << "Copy Constructor: Copied " << size << " integers." << std::endl;
    }

    // 拷贝赋值运算符
    ResourceHolder& operator=(const ResourceHolder& other) {
        if (this != &other) {
            delete[] data;
            size = other.size;
            data = new int[size];
            for (size_t i = 0; i < size; ++i) {
                data[i] = other.data[i];
            }
            std::cout << "Copy Assignment Operator: Copied " << size << " integers." << std::endl;
        }
        return *this;
    }

    // 移动构造函数
    ResourceHolder(ResourceHolder&& other) noexcept : data(other.data), size(other.size) {
        other.data = nullptr;
        other.size = 0;
        std::cout << "Move Constructor: Moved resources." << std::endl;
    }

    // 移动赋值运算符
    ResourceHolder& operator=(ResourceHolder&& other) noexcept {
        if (this != &other) {
            delete[] data;
            data = other.data;
            size = other.size;
            other.data = nullptr;
            other.size = 0;
            std::cout << "Move Assignment Operator: Moved resources." << std::endl;
        }
        return *this;
    }
};

利用移动语义,在移动构造函数和移动赋值运算符中,我们直接接管源对象的资源(data指针和size),并将源对象的资源指针设为nullptr,大小设为0。这样避免了内存的拷贝,提高了效率。当源对象析构时,由于指针为nullptr,不会导致内存释放错误。