为了将我的问题背景化,我使用了具有以下定义的 Matrix 类:
Matrix(unsigned int, unsigned int); // matrix of the given dimension full of zeroes
Matrix(Matrix*); // creates a new matrix from another one
int &operator()(int, int); // used to access the matrix
int **matrix; // the matrix
现在看这两个代码片段:
首先:
Matrix test(4,4);
Matrix ptr = test;
ptr(0,0) = 95;
第二个:
Matrix test(4,4);
Matrix *ptr = &test;
(*ptr)(0,0) = 95;
两段代码效果一样,(0,0)位置的元素收到95(第一个片段和Java很像,所以才问这个问题)。 问题是,这两种方式都正确地进行了对象的赋值吗?
最佳答案
这有点复杂。
考虑这个简单的类:
class Thing1
{
public:
int n;
}
现在我们开始第一个实验:
Thing1 A;
A.n = 5;
Thing1 B = A;
B.n = 7;
cout << A.n << " " << B.n << endl;
结果是“5 7”。 A
和B
是两个独立的对象。改变一个不会改变另一个。
第二个实验:
Thing1 *p = &A;
p->n = 9;
cout << A.n << " " << p->n << endl;
结果是“9 9”; p
是指向A
的指针,所以A.n
和p->n
是同一事物。
现在事情变得复杂了:
class Thing2
{
public:
int *p;
};
...
Thing2 A;
A.p = new int(2);
Thing2 B = A;
*(B.p) = 4;
cout << *(A.p) << " " << *(B.p) << endl;
现在结果是“4 4”。赋值 B = A
复制了指针,所以尽管 A
和 B
是两个不同的对象,但它们的指针指向到同一个整数。这是一个浅拷贝。一般来说,如果你想制作一个深拷贝(也就是说,每个 Thing 都指向它自己的一个 int),你必须手动完成或者给类一个赋值运算符 将处理它。由于您的 Matrix
类没有显式赋值运算符,因此编译器为其提供了默认值——即浅拷贝。这就是为什么在您的第一个代码段中,两个矩阵似乎都已更改。
编辑:感谢@AlisherKassymov,他指出 Thing A=B;
形式的声明使用复制构造函数, 不赋值运算符。 因此,要使上述代码中的解决方案生效,复制构造函数必须进行深度复制。 (请注意,如果复制构造函数执行此操作,您几乎肯定希望赋值运算符也执行此操作(参见 Rule of Three ))。另请注意,如果这些函数变得复杂,则只需让复制构造函数调用赋值运算符即可。)
关于c++ - C++中对象的赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19919434/