【问题标题】:Instantiating an Array of Objects, but it is working like static objects实例化一个对象数组,但它像静态对象一样工作
【发布时间】:2017-05-18 00:29:27
【问题描述】:

所以我初始化了一个多项式数组。

Polynomial* pArray;
pArray = new Polynomial[size];

for (int r = 0; r < size; r++){
    pArray[r] = Polynomial(p.size);
}

当我改变 pArray 中任何多项式的系数时,它都会改变所有的系数。

pArray[1].coefficients[0] = 12;
cout << pArray[1].coefficients[0] << "\n";
//print coefficients
for (int i = 0; i < size; i++){
    for (int j = 0; j < p.size; j++){
        cout << pArray[i].coefficients[j] << " ";
        }

输出:

12 0 12 0 12 0

我不希望这种情况发生。当我设置一个多项式的系数时,我不希望它影响其他的。我该怎么做?

【问题讨论】:

  • 显示class Polynomial的定义。 p 是什么?
  • 我敢打赌这是Rule of Three违规。 pArray[r] = Polynomial(p.size) 行在一个可能不支持它的类上调用默认赋值或复制构造,尽管它管理自己的内存。
  • 嗨,看看minimal reproducible example 并尝试清理一下问题

标签: c++ arrays object static instantiation


【解决方案1】:

从您显示的代码来看,coefficients 可能是由构造函数Polynomial(int) 初始化的指针。从你描述的行为来看,我很确定即使你没有上课,我也会回答你的问题。

几乎可以肯定,这就是它的样子。这里我假设它存储int 值:

class Polynomial {
public:
    Polynomial() : coefficients(nullptr), size(0) {}
    Polynomial( int s ) : coefficients(new int[s]), size(s) {}
    ~Polynomial() { delete [] coefficients; }
    int * coefficients;
    int size;
};

所以现在问题来了。你违反了Rule of Three,因为没有为管理自己内存的类提供复制或赋值构造函数。

当你这样做时:

for (int r = 0; r < size; r++){
    pArray[r] = Polynomial(p.size);
}

会发生什么:

  1. Polynomial(p.size)构造一个临时值
  2. 当前的pArray[r] 值被破坏
  3. 调用赋值操作符,默认情况下,它会将临​​时数据成员直接复制到pArray[r]
  4. 步骤 1 中的临时值被破坏。

注意第 4 步。您将 指针 复制到另一个对象中,然后删除了该指针。现在你有了未定义的行为。在您的情况下,可能发生的情况是对 new 的调用总是返回相同的指针。这不能保证。当您有未定义的行为时,没有任何保证。但它确实给出了一个强烈的暗示,促使我写下这个答案。

要解决此问题,您必须为对象定义一个复制构造函数,该构造函数分配一个新的 coefficients 数组并将数据复制到该数组中。

Polynomial::Polynomial( const Polynomial & p )
: coefficients( new int [p.size] )
, size( p.size )
{
    std::copy( p.coefficients, p.coefficients+size, coefficients );
}

或者更好的是,将您的系数存储在std::vector 中。毕竟,您使用的是 C++。那么您就不必担心新建、删除、复制或移动(我决定从这个答案中省略这个概念)。

如果你必须分配,那么至少将指针存储为std::unique_ptr——当你试图复制你的对象时,它会立即给你一个编译错误,并强制你一个重要的复制构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 2020-03-19
    • 1970-01-01
    • 2016-05-20
    相关资源
    最近更新 更多