实例化一个对象数组,但它像静态对象一样工作
Instantiating an Array of Objects, but it is working like static objects
所以我初始化了一个多项式数组。
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
我不希望发生这种情况。当我设置一个多项式的系数时,我不希望它影响其他多项式。我该怎么做?
从您显示的代码来看,coefficients
可能是由构造函数 Polynomial(int)
初始化的指针。从您描述的行为来看,我非常确定,即使您没有显示 class.
,我也会回答您的问题
这几乎就是它的样子。在这里,我假设它存储 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;
};
现在问题来了。您没有为管理自己内存的 class 提供复制或赋值构造函数,这违反了 Rule of Three。
当你这样做时:
for (int r = 0; r < size; r++){
pArray[r] = Polynomial(p.size);
}
事情是这样的:
- 临时值由
Polynomial(p.size)
构造
- 当前
pArray[r]
值被破坏
- 调用赋值运算符,默认情况下会将数据成员从临时直接复制到
pArray[r]
- 步骤 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
—— 当你试图复制你的对象,并强制你创建一个非平凡的复制构造函数。
所以我初始化了一个多项式数组。
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
我不希望发生这种情况。当我设置一个多项式的系数时,我不希望它影响其他多项式。我该怎么做?
从您显示的代码来看,coefficients
可能是由构造函数 Polynomial(int)
初始化的指针。从您描述的行为来看,我非常确定,即使您没有显示 class.
这几乎就是它的样子。在这里,我假设它存储 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;
};
现在问题来了。您没有为管理自己内存的 class 提供复制或赋值构造函数,这违反了 Rule of Three。
当你这样做时:
for (int r = 0; r < size; r++){
pArray[r] = Polynomial(p.size);
}
事情是这样的:
- 临时值由
Polynomial(p.size)
构造
- 当前
pArray[r]
值被破坏 - 调用赋值运算符,默认情况下会将数据成员从临时直接复制到
pArray[r]
- 步骤 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
—— 当你试图复制你的对象,并强制你创建一个非平凡的复制构造函数。