Does assignment operator have to behave exactly like copy constructor

B

bluekite2000

I want Matrix A(B) to create shallow copy of B but A=B to create deep
copy of B. Is that bad design? Why and why not?
 
V

Victor Bazarov

I want Matrix A(B) to create shallow copy of B but A=B to create deep
copy of B. Is that bad design? Why and why not?

To determine whether some decision (design decision included) is bad or
good, one needs to know the motivation behind the decision. Why do you
think you need them to behave differently?

The copy-construction or copy-assignment have the "copy" as their key
word. You implement them both. So, you must have a compelling reason
to make them different, otherwise, if you asked a lay person, they'd
just say, "Hey, you're making a copy either way, right? So, it should
be the same thing."

If your goal is to implement "lazy copying" or "copy-on-write" sort of
thing, then both should essentially do it, and you need to employ some
variation of reference counting. If that's not your goal, then what?

V
 
H

Howard

I want Matrix A(B) to create shallow copy of B but A=B to create deep
copy of B. Is that bad design? Why and why not?

I guess it depends on why you're doing it that way, and what your Matrix
object contains. Having different behavior between the two isn't
"inherently" bad design, but it *could* be.

If by "shallow copy" you mean that your Matrix class contains pointers or
references, or members which themselves have dynamically-allocated data, and
your copy constructor only copies the pointer or reference, then that can
certainly cause you problems. When you go to delete one of the objects, the
remaining object will then have a pointer or reference to deleted data. But
this is a problem with the copy constructor itself, not with the assignment
operator being different.

Without seeing your design, we can't say for sure if it's wrong or not. The
question is, WHY do want them different? And be sure you understand when
each of those functions wil be called. (For instance, you know that
"MyClass x = y;" is an initialization, not an assignment, right?

-Howard
 
P

Panjandrum

I want Matrix A(B) to create shallow copy of B but A=B to create deep
copy of B. Is that bad design? Why and why not?

1. It's bad design because it violates the rule of least surprise.
2. You don't need it:
Matrix& A = B;
 
A

Andre Kostur

(e-mail address removed) wrote in @g44g2000cwa.googlegroups.com:
I want Matrix A(B) to create shallow copy of B but A=B to create deep
copy of B. Is that bad design? Why and why not?

Highly unadvisable.

Principle of least surprise. What would the two code snippets do
(assuming the appropriate operator definitions, and that a and b can be
added together... it's been a long time since I've had to do linear
algebra...):

{
Matrix a, b;

// Fill a and b with something reasonable

Matrix c(a); // Shallow copy

c += b;
}

vs.

{
Matrix a, b;

// Fill a and b with something reasonable

Matrix c;

c = a; // Deep copy
c += b;
}


What would the contents of a, b, and c be in both cases?
 
H

Howard

Panjandrum said:
1. It's bad design because it violates the rule of least surprise.

I think you're making that one up! :)
2. You don't need it:
Matrix& A = B;

How does that help? It's not a copy at all, but a reference to an existing
object. Any changes you then make to the members of A also happen to the
members of B (and vise-versa).

-Howard
 
V

Victor Bazarov

Andre said:
(e-mail address removed) wrote in @g44g2000cwa.googlegroups.com:




Highly unadvisable.

Principle of least surprise. What would the two code snippets do
(assuming the appropriate operator definitions, and that a and b can be
added together... it's been a long time since I've had to do linear
algebra...):

{
Matrix a, b;

// Fill a and b with something reasonable

Matrix c(a); // Shallow copy

c += b;
}

vs.

{
Matrix a, b;

// Fill a and b with something reasonable

Matrix c;

c = a; // Deep copy
c += b;
}


What would the contents of a, b, and c be in both cases?

The same because += actually makes a deeper copy behind the scenes. It's
called "copy-on-write". Of course, a simple assignment could be made to
perform shallow copy just as well in that case...

(It's a speculation, of course. The OP should answer this question,
however, it basically goes to the argument that you cannot answer the
original question without knowing more about the Matrix design and its
intentions)

V
 
A

Andre Kostur

The same because += actually makes a deeper copy behind the scenes. It's
called "copy-on-write". Of course, a simple assignment could be made to
perform shallow copy just as well in that case...

I'm assuming no COW in play here since the OP has two different semantics
for copy construction and assignment (suggesting that the OP isn't aware
of all of the implications behind that decision).... as you mentioned, if
COW was in play, there's no point in doing a deep copy during the
assignment.
 
B

bluekite2000

Say I have M=1 3
2 4
V=0
0
Vector Vcol=M.Col(1) //shallow copying
M.Col(1) =V //shallow copying
cout<<M<<endl;
1 3
2 4
cout<<Vcol<<endl;
3
4

But I want M to = 1 0
2 0

So I changed my assignment operator to do deep copying, thus solving
the problem.
 
P

Panjandrum

Howard said:
How does that help? It's not a copy at all, but a reference to an existing
object. Any changes you then make to the members of A also happen to the
members of B (and vise-versa).

And what is a 'shallow copy' supposed to do?
 
H

Howard

Panjandrum said:
And what is a 'shallow copy' supposed to do?

I believe a "shallow copy" of an object means that the object's contents are
copied bit-wise. In that case, member pointers and references end up
pointing at the same addresses in both the original and the newly created
object.

A "deep copy" would be a member-wise copy, so that dynamic members would
also be copy-constructed. The pointers and references in the new object
would thus point to different addresses than the original's.

-Howard
 
P

Panjandrum

Howard said:
I believe a "shallow copy" of an object means that the object's contents are
copied bit-wise. In that case, member pointers and references end up
pointing at the same addresses in both the original and the newly created
object.

not the 'usual' definition, see e.g.
http://en.wikipedia.org/wiki/Shallow_copy
A "deep copy" would be a member-wise copy, so that dynamic members would
also be copy-constructed. The pointers and references in the new object
would thus point to different addresses than the original's.

agreed
 
H

Howard

Panjandrum said:
not the 'usual' definition, see e.g.
http://en.wikipedia.org/wiki/Shallow_copy

I'm pretty sure I gave the "usual" definition.

That article is incorrect, in part. Here it is:

"In computing, a deep copy is copy that contains the complete encapsulated
data of the original object, allowing it to be used independently of the
original object. In contrast, a shallow copy is a copy that may be
associated to data shared by the original and the copy.

"For example, if a C++ class contains a pointer to a null-terminated string,
the deep copy would also copy the string, while the shallow copy would
create an object where the pointer points to same string, and changes to it
affect both objects.

---> That's correct information, as far as I know. Note that it talks about
a pointer *inside* a C++ class, which is exactly what I described. The
shallow copy creates an object where the pointer (inside the object) points
to the same string. Anything you do to the string *inside* one object, is
doing it to the string inside the other object as well.


"In computing, the result of shallow copying one object to another variable
is two variables pointing to the same physical object in memory.

---> But that paragraph is mis-stated, I am sure. It talks about copying an
object to a variable, making two variables point to the same object. But
copying an object is not the same as copying a pointer, and there is no way
to "copy" a reference, only to initialize one (at least in C++). I would
bet that's not what they were trying to say, and that they just worded the
idea poorly that the pointers or references *inside* the objects point to
the same location after a shallow copy.


"Thus changing the object pointed to by one of the variables will also cause
the contents of the other variable to change (since the same object in
memory is being altered).

"Shallow copies are common when reference counting objects. The technique is
by default when copying objects in Java."

---> Fix that one paragraph, and the rest is as I stated.


-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top