Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assignment of objects in C++

To contextualize my question, I'm using a Matrix class with the following definitions:

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

Now take these two code snippets:

First:

Matrix test(4,4);
Matrix ptr = test;
ptr(0,0) = 95;

Second:

Matrix test(4,4);
Matrix *ptr = &test;
(*ptr)(0,0) = 95;

Both codes have the same effect, the element in the (0,0) position receives 95 (The first snippet is very similar to Java, the reason which led me to ask this question). The question is, are both ways correctly making the assignment of the object?

like image 887
user1493813 Avatar asked Nov 12 '13 01:11

user1493813


People also ask

Can you assign objects C++?

Unlike other object-oriented languages like Java, C++ has robust support for object deep-copying and assignment. You can choose whether to pass objects to functions by reference or by value, and can assign objects to one another as though they were primitive data types.

How do you assign one object to another object in CPP?

Copy Constructor in C++ ClassName (const ClassName &old_obj); Copy constructor is used to initialize the members of a newly created object by copying the members of an already existing object. Copy constructor takes a reference to an object of the same class as an argument.

Is <- an assignment operator?

The assignment operator = assigns the value of its right-hand operand to a variable, a property, or an indexer element given by its left-hand operand. The result of an assignment expression is the value assigned to the left-hand operand.


1 Answers

This is a little complicated.

Consider this simple class:

class Thing1
{
public:
  int n;
}

Now we try the first experiment:

Thing1 A;
A.n = 5;

Thing1 B = A;
B.n = 7;

cout << A.n << " " << B.n << endl;

The result is "5 7". A and B are two separate, independent objects. Changing one doesn't change the other.

Second experiment:

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

cout << A.n << " " << p->n << endl;

The result is "9 9"; p is a pointer to A, so A.n and p->n are the same thing.

Now things get complicated:

class Thing2
{
public:
  int *p;
};

...
Thing2 A;
A.p = new int(2);

Thing2 B = A;
*(B.p) = 4;

cout << *(A.p) << " " << *(B.p) << endl;

Now the result is "4 4". The assignment B = A copied the pointer, so although A and B are two different objects, their pointers point to the same int. This is a shallow copy. In general, if you want to make a deep copy (that is, each Thing points to an int of its own) you must either do it by hand or give the class an assignment operator which will handle it. Since your Matrix class doesn't have an explicit assignment operator, the compiler gives it the default-- which is a shallow copy. That's why, in your first snippet, both matrices appear to be changed.

EDIT: Thanks to @AlisherKassymov, for pointing out that declarations of the form Thing A=B; use the copy constructor, not the assignment operator. So for the solution to work in the above code, the copy constructor must make a deep copy. (Note that if the copy constructor does it, you almost certainly want the assignment operator to do it too (see the Rule of Three)). Also note that if these functions get complicated, it makes sense to simply have the copy constructor invoke the assignment operator.)

like image 86
Beta Avatar answered Oct 13 '22 21:10

Beta