用C++分配对象

use*_*813 8 c++ object variable-assignment assign

为了对我的问题进行语境化,我使用的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
Run Code Online (Sandbox Code Playgroud)

现在拿这两个代码片段:

第一:

Matrix test(4,4);
Matrix ptr = test;
ptr(0,0) = 95;
Run Code Online (Sandbox Code Playgroud)

第二:

Matrix test(4,4);
Matrix *ptr = &test;
(*ptr)(0,0) = 95;
Run Code Online (Sandbox Code Playgroud)

两个代码都有相同的效果,(0,0)位置的元素接收95(第一个代码片段与Java非常相似,这是导致我提出这个问题的原因).问题是,两种方式都正确地分配了对象吗?

Bet*_*eta 26

这有点复杂.

考虑这个简单的类:

class Thing1
{
public:
  int n;
}
Run Code Online (Sandbox Code Playgroud)

现在我们尝试第一个实验:

Thing1 A;
A.n = 5;

Thing1 B = A;
B.n = 7;

cout << A.n << " " << B.n << endl;
Run Code Online (Sandbox Code Playgroud)

结果是"5 7".A并且B是两个独立的独立对象.改变一个不会改变另一个.

第二个实验:

Thing1 *p = &A;
p->n = 9;

cout << A.n << " " << p->n << endl;
Run Code Online (Sandbox Code Playgroud)

结果是"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;
Run Code Online (Sandbox Code Playgroud)

现在结果是"4 4".分配B = A复制的指针,所以虽然AB是两个不同的对象,它们的指针指向同一个int类型.这是一个浅表副本.一般来说,如果你想做一个深层复制(也就是说,每个Thing指向它自己的一个int),你必须手工完成它或给类一个将处理它的赋值运算符.由于您的Matrix类没有显式赋值运算符,编译器会为其赋予默认值 - 这是一个浅表副本.这就是为什么在你的第一个片段中,两个矩阵似乎都被改变了.

编辑:感谢@AlisherKassymov,指出表单的声明Thing A=B;使用复制构造函数,而不是赋值运算符.因此,要使解决方案在上面的代码中工作,复制构造函数必须进行深层复制.(请注意,如果复制构造函数执行它,您几乎肯定希望赋值运算符也这样做(请参阅规则三).另请注意,如果这些函数变得复杂,只需让复制构造函数调用赋值即可运营商.)

  • 我不认为这是正确的.在这种情况下,使赋值运算符重载不会更改结果.这是一个复制构造函数.为了使赋值运算符起作用,首先需要构造对象,然后使用=来复制另一个对象 (3认同)

Atl*_*tle 5

这两者并不相等.

第一个片段

Matrix test,与完整的内容是COPIED成Matrix ptr.当你工作ptr后,你只改变副本,而不是原来的Matrix test.

第二个片段

地址Matrix test被放入指针Matrix *ptr.指针现在保存地址test.在编写时(*ptr),您取消引用指针并使用原始值test.

在Java中

在java中,所有对象都是指针(类似int的原语不是).当您将一个对象分配给另一个对象时,默认情况下仅覆盖指针值.就像你的第二个例子一样.