MST
星途 面试题库

面试题:C++ 重写拷贝构造函数中资源管理的复杂场景

假设有一个C++类,它不仅包含动态分配的内存,还持有一个文件描述符(假设使用`int`表示)。在重写拷贝构造函数时,需要考虑如何正确处理内存和文件描述符的拷贝,同时要避免资源泄漏。请实现该类及其重写的拷贝构造函数,并解释你的设计思路。
47.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

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

class MyClass {
private:
    char* data;
    int fileDescriptor;
public:
    // 构造函数
    MyClass(const char* str, int fd) {
        if (str) {
            data = new char[strlen(str) + 1];
            std::strcpy(data, str);
        } else {
            data = nullptr;
        }
        fileDescriptor = fd;
    }

    // 拷贝构造函数
    MyClass(const MyClass& other) {
        if (other.data) {
            data = new char[strlen(other.data) + 1];
            std::strcpy(data, other.data);
        } else {
            data = nullptr;
        }
        fileDescriptor = other.fileDescriptor;
    }

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

    // 打印函数
    void print() const {
        if (data) {
            std::cout << "Data: " << data << ", File Descriptor: " << fileDescriptor << std::endl;
        } else {
            std::cout << "Data is nullptr, File Descriptor: " << fileDescriptor << std::endl;
        }
    }
};

设计思路

  1. 数据成员
    • data 是一个动态分配的字符数组,用于存储字符串数据。
    • fileDescriptor 是一个整数,表示文件描述符。
  2. 构造函数
    • 构造函数接受一个字符串和文件描述符作为参数。它根据传入的字符串动态分配内存并复制字符串内容,同时初始化文件描述符。
  3. 拷贝构造函数
    • 拷贝构造函数接受一个 MyClass 对象的常量引用。
    • 对于动态分配的内存 data,如果源对象的 data 不为空,它会分配新的内存并复制源对象 data 中的内容。这样做是为了避免两个对象共享同一块内存,防止释放内存时出现重复释放或悬空指针的问题。
    • 对于文件描述符 fileDescriptor,直接进行值拷贝。因为文件描述符在进程内是唯一标识一个打开文件的整数,通常不需要特殊的拷贝处理(比如创建一个新的文件描述符副本指向同一文件,在POSIX系统中可以使用 dup 等函数,但这里假设直接值拷贝即可满足需求)。
  4. 析构函数
    • 析构函数负责释放动态分配的内存 data,避免内存泄漏。

通过以上设计,在拷贝对象时,既正确处理了动态分配内存的深拷贝,又合理处理了文件描述符的拷贝,同时避免了资源泄漏。