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

Checking assignment operators with *this pointer

P: n/a
Hey,

I know we use the pointer this to obtain a class object or class
member data. I don't follow the reason for example this code. I'am
quite confused

assingment operator
const B &operator=(const B& x){

if (&x != this)
a = x.a;

else
return *this;
}
This is how i see this code. its compares the reference of x to the
adress of the this pointer??

In a line like this, i don't follow the steps the compiler takes.
b1 = b2;

Code below

---------------------------------------------------------------------
#include <iostream>
using namespace std;
class A
{
int n ;

public:
A():n(0)
{
}
A(int x):n(x)
{
n = x;
}
A(A &c):n(){

n = c.n;
}
void print()
{ cout << n<<"\n\n";
}
A(const A& objectCopy){
n = objectCopy.n; // copy constructor
}
const A &operator=(const A x){
n = x.n; // Operator

}
void good(){
cout<< this->n<<"";
}

};
class B
{
A * a;

int v;

public:
B(A & x)
{
a = new A(x);
}
void print ()
{
a->print();
}
B(const B& copy){ // Class B copy constructor
a = copy.a;

}
const B &operator=(const B& x){
if (&x != this)
a = x.a;
else
return *this;

// return *this;
//delete a;
}
B::~B(){
delete a;
}

};
//-------------------------------------------------------------------------*--

int main()
{

{

A a1(5);
A a2(7);
B b1(a2);
b1.print();
B b2(a1);
b1 = b2;
b1.print();
a1.good();

}

cout << endl;
int trick;
cin >trick;
return 0;
}
//-------------------------------------------------------------------------*-------
thnak you

Apr 25 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
john wrote:
Hey,

I know we use the pointer this to obtain a class object or class
member data. I don't follow the reason for example this code. I'am
quite confused

assingment operator
const B &operator=(const B& x){

if (&x != this)
a = x.a;

else
'else' should be dropped.
return *this;
}
This is how i see this code. its compares the reference of x to the
adress of the this pointer??
No, it compares the _address_ of the 'x' object to the 'this' pointer.
>
In a line like this, i don't follow the steps the compiler takes.
b1 = b2;
Have you tried looking at assembly or stepping through the code in
a debugger? It helps.
>
Code below
[..snip..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 25 '07 #2

P: n/a
"john" <wo*********@gmail.comwrote in message
news:11*********************@o40g2000prh.googlegro ups.com...
Hey,

I know we use the pointer this to obtain a class object or class
member data. I don't follow the reason for example this code. I'am
quite confused

assingment operator
const B &operator=(const B& x){

if (&x != this)
a = x.a;

else
return *this;
}
This is how i see this code. its compares the reference of x to the
adress of the this pointer??

In a line like this, i don't follow the steps the compiler takes.
b1 = b2;

Code below
[snip code]

It's to check for self assignment. Consider.

myclass A;

A = A;

This could also occur using pointers. You get an instance of myclass using
new and through the course of the program wind up trying to assign the
instance to itself.

In a trivial program where a is a built in type it's not a problem. But
there are casses where you may be storing things on the stack. Consider the
case where a is actually a pointer. An assignment operator would be tempted
to do something like this:

// consider a to be an int pointer. consider size to be a variable with
it's size.
const B &operator=(const B& x)
{
delete a;
a = new int[x.size]
for ( size_t i = ; i < size; ++i )
a[i] = x.a[i];

return *this;
}

Seems all well and good. We delete our current array, create a new one with
the proper size, then copy the contents. But what happens when self
assignment occurs? When x is actually this. As soon as we delete a we just
screwed up. We no longer have the memory to copy from, since we just
released it. That's where we check to make sure we aren't doing self
assignment.

const B &operator=(const B& x)
{
if ( &x != this )
{
delete a;
a = new int[x.size]
for ( size_t i = ; i < size; ++i )
a[i] = x.a[i];
}

return *this;
}

this is a pointer to our current instance. It compares it with the address
of the instance to copy from. If they are the same, then self assignment is
occuring. We don't have to copy or assign anything, since we'd just be
copying from ourselves.
Apr 25 '07 #3

P: n/a
On Apr 25, 5:38 am, "Jim Langston" <tazmas...@rocketmail.comwrote:
"john" <worldsou...@gmail.comwrote in message
news:11*********************@o40g2000prh.googlegro ups.com...
I know we use the pointer this to obtain a class object or class
member data. I don't follow the reason for example this code. I'am
quite confused
assingment operator
const B &operator=(const B& x){
if (&x != this)
a = x.a;
else
return *this;
}
There is no reason for such code. It is completely incorrect.
This is how i see this code. its compares the reference of x to the
adress of the this pointer??
In a line like this, i don't follow the steps the compiler takes.
b1 = b2;
Code below
[snip code]
It's to check for self assignment.
Which if necessary, is generally an indication of an error
elsewhere in the operator.
Consider.
myclass A;
A = A;
This could also occur using pointers. You get an instance of myclass using
new and through the course of the program wind up trying to assign the
instance to itself.
Not just with new. In fact, most of the time, self assignment
occurs when working with arrays of the objects.
In a trivial program where a is a built in type it's not a problem.
If it's a problem, it's a problem with the assignment operator
of a.
But there are casses where you may be storing things on the
stack. Consider the case where a is actually a pointer. An
assignment operator would be tempted to do something like
this:
// consider a to be an int pointer. consider size to be a variable with
it's size.
const B &operator=(const B& x)
{
delete a;
a = new int[x.size]
for ( size_t i = ; i < size; ++i )
a[i] = x.a[i];
return *this;
}
Seems all well and good.
No it doesn't. What happens if the new expression fails?
We delete our current array, create a new one with
the proper size, then copy the contents. But what happens when self
assignment occurs? When x is actually this. As soon as we delete a we just
screwed up. We no longer have the memory to copy from, since we just
released it. That's where we check to make sure we aren't doing self
assignment.
But the code is broken even without self-assignment. Checking
for self assignment doesn't fix this.
const B &operator=(const B& x)
{
if ( &x != this )
{
delete a;
a = new int[x.size]
for ( size_t i = ; i < size; ++i )
a[i] = x.a[i];
}
return *this;
}
Which still has the same problem as the original. If the new
expression fails, you end up with an object that cannot be
destructed.
this is a pointer to our current instance. It compares it with the address
of the instance to copy from. If they are the same, then self assignment is
occuring. We don't have to copy or assign anything, since we'd just be
copying from ourselves.
The correct way of handling this is to build up the new object
first, before the delete:

B&
B::operator=(
B const& other )
{
X* newA = new int[ other.size ] ;
for ( size_t i = 0 ; i < other.size ; ++ i ) {
newA[ i ] = other.a[ i ] ;
}
delete a ;
size = other.size ;
a = newA ;
return *this ;
}

Alternatively, you can use the swap idiom:

void
B::swap( B& other ) throw()
{
std::swap( size, other.size() ) ;
std::swap( a, other.a ) ;
}

B&
B::operator=(
B const& other )
{
B tmp( other ) ;
swap( tmp ) ;
return *this ;
}

This has the advantage of being simple to understand. It's
widely used, and can be considered idiomatic C++. It's
supported by the standard library (e.g. all of the standard
containers have no-throw versions of swap).

You'll notice, of course, that no check for self assignment is
necessary.

--
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

Apr 26 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.