实例化一个对象数组,但它像静态对象一样工作

时间:2017-05-18 00:29:28

标签: c++ arrays object static instantiation

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

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

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

1 个答案:

答案 0 :(得分:0)

从您显示的代码中,看起来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. 构成
  3. 当前pArray[r]值被破坏
  4. 调用赋值运算符,默认情况下会将临时数据成员直接复制到pArray[r]
  5. 第1步的临时值被破坏。
  6. 注意步骤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 - 当你试图复制你的对象时会立即给你一个编译错误,并强迫你制作一个非平凡的复制构造函数。