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 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.
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.
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
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
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
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)
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.
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)
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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....
|
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...
|
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...
|
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)
|
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...
|
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
{
};...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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 :...
|
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...
|
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...
|
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...
|
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...
|
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...
| |