472,993 Members | 2,122 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,993 software developers and data experts.

default implementation of assignment operator

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
9 3760
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
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
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
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: forums_mp | last post by:
After reading a few texts - nameley koeing/moo and eckel - I decided to investigating the importance of templates. Of course there's no substitute for practice so I figured I try a simple program....
10
by: cppaddict | last post by:
Hi, I am writing a program and needs to know one of its object members before it can be initialized. It doesn't really matter for my question (which a C++ question, not a windows question), but...
7
by: Mikhail N. Kupchik | last post by:
Hi All. I have a question regarding Herb Sutter's idiom of implementation of operator= via nonthrowing swap() member function, to guarantee strict exception safety. The idea of the idiom is...
7
by: Dev | last post by:
Hello, In the following class definition, the ZString destructor is invoked two times. This crashes the code. class ZString { public: ZString(char* p)
18
by: lchian | last post by:
Hi, I have a vector of class Foo. When I do a push_back(), I expect stl to call the default constructor I wrote for Foo. But instead, stl makes up its own default that is initialized with...
4
by: moleskyca1 | last post by:
Hi, In a recent discussion, some of us were in disagreement about the functions the C++ compiler generates. How many functions are generated by the compiler when you declare: class Foo { };...
43
by: JohnQ | last post by:
Are a default constructor, destructor, copy constructor and assignment operator generated by the compiler for a struct if they are not explicitely defined? I think the answer is yes, because...
2
by: George2 | last post by:
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...
9
by: puzzlecracker | last post by:
From my understanding, if you declare any sort of constructors, (excluding copy ctor), the default will not be included by default. Is this correct? class Foo{ public: Foo(int); // no...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
3
SueHopson
by: SueHopson | last post by:
Hi All, I'm trying to create a single code (run off a button that calls the Private Sub) for our parts list report that will allow the user to filter by either/both PartVendor and PartType. On...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.