You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++类中动态数组实现示例:析构与拷贝构造函数应用

我正好可以帮你实现这个Labtest类的示例,完美结合析构函数、拷贝构造函数这些关键知识点,同时满足你的功能需求。下面是完整的实现和详细解释:

实现带动态数组的Labtest类(含析构、拷贝构造、add方法及友元max函数)

核心设计思路

我们要构建的Labtest类核心结构和功能如下:

  • 私有成员:
    • ntest:整数类型,记录当前动态数组的测试数据数量
    • values:动态分配的int数组,存储ntest个测试数值
  • 核心功能:
    • add方法:给动态数组扩容一位,将新测试值追加到数组末尾
    • 友元函数max:接收Labtest对象,返回数组中的最大值
    • 手动实现拷贝构造函数和析构函数,解决动态数组的浅拷贝内存问题

完整代码实现

#include <iostream>
#include <algorithm> // 用于std::max_element工具

class Labtest {
private:
    int ntest;
    int* values;

public:
    // 默认构造函数:初始化空数组
    Labtest() : ntest(0), values(nullptr) {}

    // 拷贝构造函数:深拷贝避免浅拷贝内存问题
    Labtest(const Labtest& other) {
        ntest = other.ntest;
        // 为新对象分配独立内存
        values = new int[ntest];
        // 逐个拷贝元素
        for (int i = 0; i < ntest; ++i) {
            values[i] = other.values[i];
        }
    }

    // 析构函数:释放动态分配的内存,防止内存泄漏
    ~Labtest() {
        delete[] values;
        values = nullptr; // 置空指针避免野指针
    }

    // 重载赋值运算符(可选但推荐,和拷贝构造配套)
    Labtest& operator=(const Labtest& other) {
        if (this == &other) { // 防止自赋值导致的内存错误
            return *this;
        }

        // 先释放当前对象的旧内存
        delete[] values;

        // 执行深拷贝
        ntest = other.ntest;
        values = new int[ntest];
        for (int i = 0; i < ntest; ++i) {
            values[i] = other.values[i];
        }

        return *this;
    }

    // add方法:扩容数组并添加新元素
    void add(int num) {
        // 分配比原数组大1的新内存
        int* new_values = new int[ntest + 1];
        // 拷贝原有元素到新数组
        for (int i = 0; i < ntest; ++i) {
            new_values[i] = values[i];
        }
        // 添加新元素到末尾
        new_values[ntest] = num;
        // 释放旧数组内存
        delete[] values;
        // 更新指针和计数
        values = new_values;
        ntest++;
    }

    // 友元函数:计算数组最大值
    friend int max(const Labtest& test) {
        if (test.ntest == 0) {
            std::cerr << "Error: No test values available!" << std::endl;
            return -1; // 也可以抛出异常,根据需求调整
        }
        // 使用std::max_element快速查找最大值,也可手动遍历实现
        return *std::max_element(test.values, test.values + test.ntest);
    }

    // 辅助方法:打印数组内容,方便测试
    void printValues() const {
        std::cout << "Test values: ";
        for (int i = 0; i < ntest; ++i) {
            std::cout << values[i] << " ";
        }
        std::cout << std::endl;
    }
};

// 测试代码
int main() {
    Labtest test1;
    test1.add(85);
    test1.add(92);
    test1.add(78);
    test1.add(95);

    std::cout << "Test1: ";
    test1.printValues();
    std::cout << "Max value in test1: " << max(test1) << std::endl;

    // 测试拷贝构造函数
    Labtest test2 = test1;
    std::cout << "\nTest2 (copied from test1): ";
    test2.printValues();
    test2.add(88);
    std::cout << "Test2 after adding 88: ";
    test2.printValues();
    std::cout << "Max value in test2: " << max(test2) << std::endl;

    // 测试赋值运算符
    Labtest test3;
    test3.add(60);
    test3 = test1;
    std::cout << "\nTest3 after assignment from test1: ";
    test3.printValues();

    return 0;
}

关键知识点详解

1. 析构函数的必要性

因为我们使用new[]动态分配了数组内存,如果不手动实现析构函数,编译器生成的默认析构函数不会释放这块内存,会导致内存泄漏。析构函数会在对象生命周期结束时自动调用,确保内存被正确回收。

2. 拷贝构造函数的作用

默认的浅拷贝构造函数会让两个对象的values指针指向同一块内存,当其中一个对象被销毁时,内存被释放,另一个对象的指针就变成野指针,访问时会触发未定义行为。我们实现的深拷贝会为新对象分配独立内存,逐个拷贝元素,彻底避免这个问题。

3. add方法的扩容逻辑

每次添加元素时,我们需要:

  • 分配一块比原数组大1的新内存
  • 拷贝原数组元素到新内存
  • 追加新元素
  • 释放原数组内存并更新指针和计数

4. 友元函数max的优势

友元函数可以直接访问类的私有成员,无需额外的getter方法,这里我们用std::max_element简化最大值查找逻辑,也可以手动遍历数组实现相同功能。


测试代码输出示例

Test1: Test values: 85 92 78 95 
Max value in test1: 95

Test2 (copied from test1): Test values: 85 92 78 95 
Test2 after adding 88: Test values: 85 92 78 95 88 
Max value in test2: 95

Test3 after assignment from test1: Test values: 85 92 78 95 

内容的提问来源于stack exchange,提问作者John Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:39:43