By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,446 Members | 3,090 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,446 IT Pros & Developers. It's quick & easy.

default implementation of assignment operator

P: n/a
Hello everyone,
I am wondering the default implementation of assignment operator (e.g.
when we do not implement assignment operator in user defined class,
what will be returned? temporary object? reference or const reference?
deep copy or shallow copy is used in default assignment operator?)? I
have the C++ Programming Book at hand, but can not find it from Index
page.
thanks in advance,
George
Dec 15 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
George2 wrote:
I am wondering the default implementation of assignment operator (e.g.
when we do not implement assignment operator in user defined class,
what will be returned? temporary object? reference or const reference?
deep copy or shallow copy is used in default assignment operator?)?
The compiler cannot automatically generate a deep-copying of the
objects because it has absolutely no way of knowing whether the member
pointers are pointing at memory allocated and owned by the object
itself, or whether they are just pointing to something else (for example
trying to deep-copy an element of a doubly-linked list would be quite a
bad idea).
The default assignment operator simply assigns each individual member
variable from the parameter to this, regardless of what it is. If it's
eg. a pointer, then a simple pointer assignment will be done.

In many cases the default assignment operator is ok, especially if the
class does not contain pointers.

It returns a const-reference to *this.
Dec 15 '07 #2

P: n/a
On Dec 15, 4:22 pm, Juha Nieminen <nos...@thanks.invalidwrote:
George2 wrote:
I am wondering the default implementation of assignment operator (e.g.
when we do not implement assignment operator in user defined class,
what will be returned? temporary object? reference or const reference?
deep copy or shallow copy is used in default assignment operator?)?

The compiler cannot automatically generate a deep-copying of the
objects because it has absolutely no way of knowing whether the member
pointers are pointing at memory allocated and owned by the object
itself, or whether they are just pointing to something else (for example
trying to deep-copy an element of a doubly-linked list would be quite a
bad idea).
The default assignment operator simply assigns each individual member
variable from the parameter to this, regardless of what it is. If it's
eg. a pointer, then a simple pointer assignment will be done.

In many cases the default assignment operator is ok, especially if the
class does not contain pointers.

It returns a const-reference to *this.
Not a const reference.
Dec 15 '07 #3

P: n/a
On Dec 15, 7:06 am, George2 <george4acade...@yahoo.comwrote:
I am wondering the default implementation of assignment
operator (e.g. when we do not implement assignment operator
in user defined class, what will be returned? temporary
object? reference or const reference? deep copy or shallow
copy is used in default assignment operator?)? I have the C++
Programming Book at hand, but can not find it from Index page.
It does member by member assignment. Whether this does a deep
copy or a shallow one depends on the assignment operators in the
members, for raw pointers, it is shallow, since pointer
assignment is shallow.

The signature of the operator, for a class T, is usually:
T& T::operator=( T const& )
If any of the base classes or members have a copy assignment
operator which requires a non-const reference, however, the
parameter will be a non-const reference.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 15 '07 #4

P: n/a
Juha Nieminen wrote:
George2 wrote:
>I am wondering the default implementation of assignment operator
(e.g. when we do not implement assignment operator in user defined
class, what will be returned? temporary object? reference or const
reference? deep copy or shallow copy is used in default assignment
operator?)?

The compiler cannot automatically generate a deep-copying of the
objects because it has absolutely no way of knowing whether the member
pointers are pointing at memory allocated and owned by the object
itself, or whether they are just pointing to something else (for
example trying to deep-copy an element of a doubly-linked list would
be quite a bad idea).
The default assignment operator simply assigns each individual member
variable from the parameter to this, regardless of what it is. If it's
eg. a pointer, then a simple pointer assignment will be done.

In many cases the default assignment operator is ok, especially if
the class does not contain pointers.

It returns a const-reference to *this.
This behavior is sometimes refered to as a "bitwise copy" although that is
not strictly true. If it was a bitwise copy, copying the bits of the class
ignoring constructors, then there would be different values then there are.

Basically it will take the base copy of whatever types are being copied.
For most things this is fine. This will work for stl::containers,
std::string, std::vector, etc... but it usually does not give you want you
want for pointers. Your copied class will have it's pointers copied by
value, pointing to the same things they were pointing to before. In some
cases this may be what you want. In most cases it is not. One of the
biggest dangers of this behavior is when the destructor of the class
destroyes it's pointed to value (delete). Then your copied class may point
to data that is no longer valid.

Consider:

class Foo
{
public:
Foo() { MyData = new char[100]; }
~Foo() { delete[] MyData; }
private:
char* MyData;
}

If this class is copied, MyData will be copied by value, the pointer will be
copied, and you will have 2 instances pointing to the same portion of
memory, which is not what you want in most cases. Also, if the destructor
ever gets invoked, such as a temporary being created and destroyed, then
MyData will become invalid in the copied class. The normal way of dealing
with this is with a copy constructor that assigns it's own memory.

#include <algorithm>

class Foo
{
public:
Foo() { MyData = new char[100]; }
~Foo() { delete[] MyData; }
Foo( const Foo& rhs )
{
MyData = new char[100];
std::copy( &rhs.MyData[0], &rhs.MyData[99], MyData );
}
private:
char* MyData;
};

--
Jim Langston
ta*******@rocketmail.com
Dec 15 '07 #5

P: n/a
Jim Langston wrote:
Juha Nieminen wrote:
>George2 wrote:
>>I am wondering the default implementation of assignment operator
(e.g. when we do not implement assignment operator in user defined
class, what will be returned? temporary object? reference or const
reference? deep copy or shallow copy is used in default assignment
operator?)?

The compiler cannot automatically generate a deep-copying of the
objects because it has absolutely no way of knowing whether the
member pointers are pointing at memory allocated and owned by the
object itself, or whether they are just pointing to something else
(for example trying to deep-copy an element of a doubly-linked list
would be quite a bad idea).
The default assignment operator simply assigns each individual
member variable from the parameter to this, regardless of what it
is. If it's eg. a pointer, then a simple pointer assignment will be
done. In many cases the default assignment operator is ok, especially if
the class does not contain pointers.

It returns a const-reference to *this.

This behavior is sometimes refered to as a "bitwise copy" although
that is not strictly true. If it was a bitwise copy, copying the
bits of the class ignoring constructors, then there would be
different values then there are.
Basically it will take the base copy of whatever types are being
copied. For most things this is fine. This will work for
stl::containers, std::string, std::vector, etc... but it usually does
not give you want you want for pointers. Your copied class will have
it's pointers copied by value, pointing to the same things they were
pointing to before. In some cases this may be what you want. In most
cases it is not. One of the biggest dangers of this behavior is when
the destructor of the class destroyes it's pointed to value (delete).
Then your copied class may point to data that is no longer valid.

Consider:

class Foo
{
public:
Foo() { MyData = new char[100]; }
~Foo() { delete[] MyData; }
private:
char* MyData;
}

If this class is copied, MyData will be copied by value, the pointer
will be copied, and you will have 2 instances pointing to the same
portion of memory, which is not what you want in most cases. Also,
if the destructor ever gets invoked, such as a temporary being
created and destroyed, then MyData will become invalid in the copied
class. The normal way of dealing with this is with a copy
constructor that assigns it's own memory.
#include <algorithm>

class Foo
{
public:
Foo() { MyData = new char[100]; }
~Foo() { delete[] MyData; }
Foo( const Foo& rhs )
{
MyData = new char[100];
std::copy( &rhs.MyData[0], &rhs.MyData[99], MyData );
}
private:
char* MyData;
};
A few things, this is the copy constructor, not the assignment operator.
Both would need to be specified (see the rule of three). The assignment
operator would look just about the same.
Second,
std::copy( &rhs.MyData[0], &rhs.MyData[99], MyData );
probably needs to be
std::copy( &rhs.MyData[0], &rhs.MyData[100], MyData );
because it is my understanding that the end iterator needs to point 1 past
the data.
--
Jim Langston
ta*******@rocketmail.com
Dec 15 '07 #6

P: n/a
On 2007-12-15 13:30:40 -0500, "Jim Langston" <ta*******@rocketmail.comsaid:
Juha Nieminen wrote:
>George2 wrote:
>>I am wondering the default implementation of assignment operator
(e.g. when we do not implement assignment operator in user defined
class, what will be returned? temporary object? reference or const
reference? deep copy or shallow copy is used in default assignment
operator?)?

The compiler cannot automatically generate a deep-copying of the
objects because it has absolutely no way of knowing whether the member
pointers are pointing at memory allocated and owned by the object
itself, or whether they are just pointing to something else (for
example trying to deep-copy an element of a doubly-linked list would
be quite a bad idea).
The default assignment operator simply assigns each individual member
variable from the parameter to this, regardless of what it is. If it's
eg. a pointer, then a simple pointer assignment will be done.

In many cases the default assignment operator is ok, especially if
the class does not contain pointers.

It returns a const-reference to *this.

This behavior is sometimes refered to as a "bitwise copy" although that is
not strictly true. If it was a bitwise copy, copying the bits of the class
ignoring constructors, then there would be different values then there are.
That's a bit confusing, because of dangling references. So here's the
deal: the compiler-generated assignment operator does member-by-member
assignment, not bitwise assignment. Bitwise assignment copies the bits
(think memcpy). Member-by-member assignment uses each type's assignment
operator, and bitwise copying for builtin types.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Dec 15 '07 #7

P: n/a
Abhishek Padmanabh wrote:
> It returns a const-reference to *this.

Not a const reference.
You mean it's possible, when default assignment operators are used, to
do this: (a = b) = c; ?

I think I'm pretty sure it's not, even without trying.
Dec 15 '07 #8

P: n/a
On 2007-12-15 16:32:57 -0500, Juha Nieminen <no****@thanks.invalidsaid:
Abhishek Padmanabh wrote:
>>It returns a const-reference to *this.

Not a const reference.

You mean it's possible, when default assignment operators are used, to
do this: (a = b) = c; ?

I think I'm pretty sure it's not, even without trying.
Are you still sure after trying it?

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Dec 15 '07 #9

P: n/a
On Sat, 15 Dec 2007 10:30:40 -0800, Jim Langston wrote:
Juha Nieminen wrote:
>George2 wrote:
>>I am wondering the default implementation of assignment operator (e.g.
when we do not implement assignment operator in user defined class,
what will be returned? temporary object? reference or const reference?
deep copy or shallow copy is used in default assignment operator?)?

The compiler cannot automatically generate a deep-copying of the
objects because it has absolutely no way of knowing whether the member
pointers are pointing at memory allocated and owned by the object
itself, or whether they are just pointing to something else (for
example trying to deep-copy an element of a doubly-linked list would be
quite a bad idea).
The default assignment operator simply assigns each individual member
variable from the parameter to this, regardless of what it is. If it's
eg. a pointer, then a simple pointer assignment will be done.

In many cases the default assignment operator is ok, especially if
the class does not contain pointers.

It returns a const-reference to *this.

This behavior is sometimes refered to as a "bitwise copy" although that
is not strictly true. If it was a bitwise copy, copying the bits of the
class ignoring constructors, then there would be different values then
there are.

Basically it will take the base copy of whatever types are being copied.
For most things this is fine. This will work for stl::containers,
std::string, std::vector, etc... but it usually does not give you want
you want for pointers. Your copied class will have it's pointers copied
by value, pointing to the same things they were pointing to before. In
some cases this may be what you want. In most cases it is not. One of
the biggest dangers of this behavior is when the destructor of the class
destroyes it's pointed to value (delete). Then your copied class may
point to data that is no longer valid.
Well, generally if an object owns some pointers, they should be wrapped
in some std::auto_ptr, boost::scoped_ptr or something like this.
Otherwise you loose exception safety and gain many headaches. OTOH
compiler generated assignment operator for class with std::auto_ptr is
even more surprising, so I recommend const std::auto_ptr.

--
Tadeusz B. Kopec (tk****@NOSPAMPLEASElife.pl)
<casMercury: gpm isn't a very good web browser. fix it.
Dec 16 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.