class 中的 C++ 动态数组

c++ dynamic arrays in class

我正在尝试在 class 中使用动态数组创建一个示例,以便使用析构函数和复制构造函数。

程序的思路如下。我有 class 带有两个私有字段的 Labtest。 ntest 一个整数,它包含测试的数量和值,它是一个具有 ntest 元素的动态数组。

我添加了方法 add ,它将动态数组扩展一个并将参数添加到最后一个位置。

我添加了一个友元函数 max,它 returns 动态数组的最大元素(它通过值对象调用)以证明复制构造函数的必要性。

为了打印对象,我重载了 <<。

我添加了默认构造函数、析构函数、复制构造函数。

到目前为止我写的代码是

#include<iostream>
using namespace std;

class Labtest {
public:
    Labtest();
    Labtest(const Labtest& a);
    ~Labtest();
    friend int max(Labtest a);
    friend ostream& operator <<(ostream& out, const Labtest& lab);
    void add_value(int a);
private:
    int ntests;
    int *values;
};

int main()
{
    Labtest chem;
    chem.add_value(10); chem.add_value(20);
    cout << chem;
    cout << "the maximum is " << max(chem) << endl;
    cout << chem;
    return 0;
}

Labtest::Labtest() : ntests(0), values(NULL)
{
}

Labtest::Labtest(const Labtest & a) : ntests(a.ntests)
{
    values = new int(ntests);
    for (int i = 0; i < ntests; i++)
        values[i] = a.values[i];
}

Labtest::~Labtest()
{
    ntests = 0;
    delete[] values;
}

void Labtest::add_value(int a)
{
    int *newvalues = new int(ntests+1);
    for (int i = 0; i < ntests; i++)
        newvalues[i] = values[i];
    newvalues[ntests] = a;
    delete[] values;
    values = newvalues;
    ntests++;
}

int max(Labtest a)
{
    int m = a.values[0];
    for (int i = 1; i < a.ntests; i++)
        if (m < a.values[i])
            m = a.values[i];
    return m;
}

ostream& operator <<(ostream & out, const Labtest& lab)
{
    for (int i = 0; i < lab.ntests; i++)
        out << lab.values[i] << " ";
    out << endl;
    return out;
}

我在 Visual Studio 中遇到堆边界错误。即使我评论了对 max 函数的调用。

任何帮助将不胜感激!

当您分配数组时,您应该 int *newvalues = new int[ntests+1]; 使用方括号代替 []

new int(10) 生成一个值为 10 的 int 变量。new int[10] 生成一个包含 10 个 int 的数组。从上下文来看,很明显您打算使用第二种形式。当您调用 delete[] values;(因为 values 不是数组)或访问第一个以外的任何元素时,使用第一种形式会导致未定义的行为。

Template class sdt::vector 仅提供您需要的功能 - 无需涉及内存管理的细节。 但是如果想练习内存管理,我应该提醒你 3 个注意事项:

  1. 数组 new 运算符的语法是 new type_spec[n] 不是新的 type_spec(n)。您使用的语法只是分配一个对象并用 n 初始化它。所以用数组删除运算符处理它会导致 UB.

  2. 删除后使指针无效更安全

  3. 定义任何获取系统资源(在本例中为堆内存)的class时,通常需要定义以下函数:

    复制构造函数。

    交换函数。

    移动构造函数,通常是交换。

    Move/copy assinment operator or both, in terms of swap.

    交换方面的析构函数。

否则 - 迟早会 - 由于忘记隐式临时对象生成或其他语义而违反一项或多项资源处理规则。并且会出现异常行为。