overloaded assignment operator and copy constructor.

S

sam_cit

Hi Everyone,

I was just wondering, about the overloaded assignment operator for
user defined objects. It is used to make sure that the following works
properly,

obj1 = obj;

so the overloaded operator function performs the necessary copy of
obj's member in to obj1. Can't the same be done using copy
constructor? If so, then what is the difference between both the
mechanisms.

Thanks in advance!!!
 
N

Neelesh Bodas

Hi Everyone,

I was just wondering, about the overloaded assignment operator for
user defined objects. It is used to make sure that the following works
properly,

obj1 = obj;

so the overloaded operator function performs the necessary copy of
obj's member in to obj1. Can't the same be done using copy
constructor? If so, then what is the difference between both the
mechanisms.

Thanks in advance!!!

assignment operator is "assignment operator", copy constructor is a
"constructor". both have different semantics.

class X { };

int main()
{
X x;
X y = x; //invokes copy constructor, since y is getting constructed
y = x; // invokes copy assignment operator, since y already exists
and is merely getting assigned.
}

-N
 
A

Alf P. Steinbach

* (e-mail address removed):
Hi Everyone,

I was just wondering, about the overloaded assignment operator for
user defined objects. It is used to make sure that the following works
properly,

obj1 = obj;

so the overloaded operator function performs the necessary copy of
obj's member in to obj1. Can't the same be done using copy
constructor? If so, then what is the difference between both the
mechanisms.

Ah, good question.

First, about the difference. A constructor is used to convert raw and
possibly random bits to a valid instance. An assignment operator is
used to change the value of an existing instance, and that might entail
deallocating storage that the existing instance has a pointer to.

E.g., consider -- while disregarding optimizations --

std::string s( "blah blah" ); // Constructor, allocates storage.
s = "Foo bar"; // Assignment, deallocates + allocates new storage.

The constructor can't make any assumptions about the raw storage it's
handed, and in particular it can't assume that there's a valid pointer
in there. The assignment operator, on the other hand, must make such
assumptions, depending on the type. Conceptually the assignment
operator has to do the job of first destructing the current object and
then copy constructing a new object.

First, positive, this thinking means it's simply Wrong(TM) to express
construction in terms of assignment: it's positive because it's so easy
to see that anyone can grok it when pointed out, that assignment is
/more/ than construction, therefore, construction should not be
expressed in terms of assignment. Yet some professionals (in the sense
of being paid by an employer) have done that, and even imposed it on
others by making it part of some in-house architecture or overall
application design. It's an easy trap to fall into when your experience
is primarily with some other language where that makes sense, but in C++
it leads to horribly complicated and bug-ridden code, so don't do it.

Negative, this thinking leads naturally to a Very Dangerous(TM) way of
expressing assignment in terms of destruction and construction, which
seems to be rediscovered by every programmer learning C++:

MyType& operator=( MyType const& other )
{
this->MyType::~MyType(); // Destruct, leaving raw bits.
::new( this ) ( other ); // In-place copy construct.
return *this;
}

One reason it's very dangerous is that the copy construction just may
fail, throwing an exception, and in that case the current instance has
already been destructed, oops. Another reason it's very dangerous is
that when this operator is called on an object of a type derived from
MyType, it changes the the dynamic type of the object (oops)! Which
means it effectively imposes a requirement on derived classes to not
call MyType's copy assignment operator, on pain of Undefined Behavior,
without that requirement being enforced by the compiler.

However, while the above is Very Dangerous, it leads in just two small
steps to the common idiom for implementing assignment in terms of copy
construction. Namely, instead of destructing the current instance, copy
construct into a completely new instance, and then /swap/ the contents
with the current instance. This requires a swap operation for the type:

MyType& operator=( MyType const& other )
{
MyType temporary( other ); // Copy construct into new instance.
swap( other ); // Swap contents with new instance.
}

Here, when the temporary goes out of scope it's destructed in the normal
way, deallocating any buffers etc. that the current instance may have
had, now (after the swap) managed by the temporary.

If swap and the destructor provide the no-throw exception guarantee,
then this is also exception safe.

And the code can be further simplified (the second step) to just

MyType& operator=( MyType other )
{
swap( other );
}

Which is the common idiom. It's not always the best way to implement
assignment. But in the absence of strong reasons not to do it this way,
it should be your default implementation: always, if practical (and
since the code is so simple it's nearly always practical) implement
assignment in terms of copy construction, swap and destruction.

Cheers, and hth.,

- Alf
 
A

Alf P. Steinbach

* Alf P. Steinbach:
MyType& operator=( MyType const& other )
{
MyType temporary( other ); // Copy construct into new instance.
swap( other ); // Swap contents with new instance.

Oops, copy typo, should be "swap( temporary )".
 
R

Richard Herring

assignment operator is "assignment operator", copy constructor is a
"constructor". both have different semantics.

class X { };

int main()
{
X x;
X y = x; //invokes copy constructor, since y is getting constructed
y = x; // invokes copy assignment operator, since y already exists
and is merely getting assigned.

Not always "merely". Assignment also involves disposing of the previous
contents.
 
T

terminator

Hi Everyone,

I was just wondering, about the overloaded assignment operator for
user defined objects. It is used to make sure that the following works
properly,

obj1 = obj;

so the overloaded operator function performs the necessary copy of
obj's member in to obj1. Can't the same be done using copy
constructor? If so, then what is the difference between both the
mechanisms.

Thanks in advance!!!

constructors are -say philosofically- invoked on newly allocated
objects who do not carry any valid data, but assignment happens for
previously constructed objects that contain valid -though not
interesting - data. Thus an assignment operator might need to get read
of rubish data in some cases -often pointeriod types - while
constructors generally need not destroy anything before copying
existing data to a new location.

regards,
FM.
 
A

alexdemche

MyType& operator=( MyType const& other )

Sorry, I cannot understand what does it mean swap?

For example, while cannot we do:

MyType& operator=(MyType const& other)
{
swap(other);
return *this;
}

Please, can you describe (for example) such situation:

class MyClass
{
int* pArray; /pointer to array, need allocation memory
/...
}

what's copy constructor, operator= and swap?
 
A

Alf P. Steinbach

* (e-mail address removed):
Sorry, I cannot understand what does it mean swap?

<url: http://www.thefreedictionary.com/swap>.


For example, while cannot we do:

MyType& operator=(MyType const& other)
{
swap(other);
return *this;
}

Because here "other" is const.

Please, can you describe (for example) such situation:

class MyClass
{
int* pArray; /pointer to array, need allocation memory
/...
}

what's copy constructor, operator= and swap?

You don't need to define them if you just do

class MyClass
{
std::vectory<int> myArray;
//...
};

instead of dealing with raw arrays and pointers.

Your C++ textbook should explain constructors, assignment operators and
(hopefully) swap. If it doesn't, get yourself a better book. Which
book are you using?
 
T

terminator

Sorry, I cannot understand what does it mean swap?

For example, while cannot we do:

MyType& operator=(MyType const& other)
{
swap(other);
return *this;

}

Please, can you describe (for example) such situation:

class MyClass
{
int* pArray; /pointer to array, need allocation memory
/...

}

what's copy constructor, operator= and swap?

The term 'swap' means exchanging the values of two objects.A general
solution for swappig two objects is the famuse triple assign method:

temp=other;
other=me;
me=temp;

but in some cases there exists a short cut and we do not need to pay
that much for the swap;In such cases a swap is normally performed much
faster and easier than an assignment ,and assignment is defined in
terms of swap rather than the vice versa.(pointeroids , string &
reference counting are best examples .):

struct my_string{
public:
my_string():str(null),sz(0){};
my_string(const char *const s){/* build from null-terminated c-
style string and literals*/
sz=strlen(s);
str=new char[sz];
memcpy(str,s,sz);
};
my_string(my_string& s):str(new char[s.sz]),sz(s.sz)
{memcpy(str,s.str,sz);};

bool swap(my_string& right){
if (right==*this) return false;

//swap str:
char* temp=str;
str=right.str;
right.str=temp;

//swap sz:
sz^=right.sz;
right.sz^=sz;
sz^=right.sz;

return true;
};

bool operator==(const my_string& right){
if(sz!=right.sz) return false;
return 0==memcmp(str,right.str,sz);
};

const my_string& operator=(my_string other){
swap(other);
return *this;
};

~my_string(){delete[] str;};

private:
char* str;
size_t sz;
....//concate , find , cstr , size ... etc
};

this is not the best approach to design strings but it shares the
common swap/copy/assign method of dynamic memory management with
better solutions.If you defined swap in terms of assignment,allocation/
deallocation(new/delete) of memory would happen three times per
swap.But now swap needs no allocation/deallocation and as you can
see,assignment needs exert a deallocation in either case (destruction
of auto variable or explicit delete).

regards,
FM
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top