Click to See Complete Forum and Search --> : HELP::Operator Overloading + Constructors


DivineBlade
January 28th, 2008, 05:58 AM
thnx a ton for the earlier reply to my post regarding constructors.......it helped me a lot


i have another query......in the following snippet the overloaded assignment operator=(with const argument as reference to object) is invoked everytime i assign either a const* or an int to the object without checking its type.

however the code doesnt compile when i remove the const prefix in the overloaded assignment operator argument and it gives me a type mismatch error.

Nevertheless if i change the argument from reference to object to just an object i.e.
from
operator=(abc& ref)
to
operator=(abc ref)
......the code compiles well.........why doesnt it give the type mismatch error now????

please help me on this issue?........any links to furthur reading material as well on similar issue would be greatly appreciated


#include<iostream>
using namespace std;

class abc{

public:
abc(){};

abc(char* word){
MemberVar = word;
}

abc(int num){


}

abc& operator=(const abc& ref)
{
return(*this);
}

private:
char *MemberVar;
};

int main(){
abc object("Hello");

abc anotherObject;

anotherObject = "i Know why this works now!!!";//

anotherObject = 8;//But i dunno why this compiles

return 0;
}

GNiewerth
January 28th, 2008, 06:35 AM
Hi again,


abc AnotherObj = 8;


works because you provided a constructor that accepts an integer parameter. Itīs pretty much the same as your previous question:


abc AnotherObj = 8;

will be substitued by

abc AnotherObj = abc( 8 );


Regarding your second question:
Execute your program in single step mode and watch the difference between passing by reference and passing by value. This should answer your question.

treuss
January 28th, 2008, 07:06 AM
Hi again,

abc AnotherObj = 8;

works because you provided a constructor that accepts an integer parameter. Itīs pretty much the same as your previous question:Just to add: You can easily avoid this kind of implicit conversion by using the explicit keyword for the constructors. Though not frequently used, it is a very powerful mean to make programs more predictable.

Just replace abc(int num){


}withexplicit abc(int num) {}

DivineBlade
January 28th, 2008, 11:15 PM
Thnx a lot for the answers.......

but my question was slightly different......
I understood why the integer constructor was called .....it was an extension of the earlier concept....

However my question was that....in the same snippet



1> The overloaded assignment operator=(with const argument as reference to object) is invoked everytime i assign either a const char* or an int to the object without checking its type.

(eg. anotherObject = 8;
or
anotherObject = "Some string";)

invokes this operator......

abc& operator=(const abc& ref)
{
return(*this);
}





2> However the code doesnt compile when i remove the const prefix in the overloaded assignment operator argument and it gives me a type mismatch error.

eg. if the const prefix is removed

abc& operator=(abc& ref)
{
return(*this);
}


and if the following declarations are made
eg. anotherObject = 8;
or
anotherObject = "Some string";)


it now produces a type mismatch error
saying that rhs of operator= expects an object reference

this above part i dint understand....what effect does const have here?????



3>...............Furthermore what completely baffles me is the fact that if instead of the reference to object in the operator=() argument , if i replace by just a pass by value...... then the code compiles n works well.....pls shed some light on it
eg.
if

abc& operator=(abc& ref)
{
return(*this);
}

is replaced by

abc& operator=(abc ref)
{
return(*this);
}


and the following declarations are made
eg. anotherObject = 8;
or
anotherObject = "Some string";)
then the code compiles well.......
i fail to understand that......and any material for further reading will be greatly appreciated

Thank you

Paul McKenzie
January 29th, 2008, 12:13 AM
Simple answer:

8 and "Some string" are constants. Trying to pass these to non-const parameters isn't going to work. Non-const implies that the passed in reference is allowed to be changed, and you cannot change a const integer or a string literal.

Regards,

Paul McKenzie

phl
January 29th, 2008, 02:24 AM
1> The overloaded assignment operator=(with const argument as reference to object) is invoked everytime i assign either a const char* or an int to the object without checking its type.


I don't understand what you mean by "without checking its type", but here is what I think is happening.


anotherObject = "i Know why this works now!!!"; //
anotherObject = 8; //But i dunno why this compiles


Each of the line above first creates a temporary object and then converts it to a constant reference.


// equivalent code
anotherObject = abc("i Know why this works now!!!"); // call abc(cahr*), then call operator=(const& abc)
anotherObject = abc(8); // call abc(int), then call operator=(const& abc)


This is legal since you can initialize constant references with temporaries.

However, if you remove "const", your code becomes illegal since a non-const reference has to be initialized with an lvalue, and a temporary cannot be an lvalue.


// On the other hand, this is legal
anotherObject = object;

treuss
January 29th, 2008, 05:11 AM
Each of the line above first creates a temporary object and then converts it to a constant reference.[...] creates a temporary object and then passes to operator=() a constant reference to that temporary object.

Sorry for nitpicking, but let's not have newbees think about converting objects into references. ;)

DivineBlade
January 29th, 2008, 05:12 AM
thnk u very much people for your timely replies.....

it really helped me clear my fundamentals.....

However just one more thing remains......


As per what Paul McKenzie said, the const keyword in the argument of operator=() tells the compiler that the operator function expects a reference to constant object and if I remove the const keyword from the operator=() definition and pass "some string" or an int then it would give an error...ok dat I got ..... but what i dint get is dat......in this case if instead of passing by reference if i define the operator=() with an argument
(object) passed by value then the code compiles and the operator=() is invoked even for
anotherObject = "Why does this work????";

anotherObject = 8;


but if the operator is defined as
abc& operator=(abc &ref)
{
return(*this);
}

I get error for anotherObject = "some string";

anotherObject = 8;

is this because im passing "some string" as a literal char?????

what ifabc& operator=(abc &ref)
{
return(*this);
}


and
char* temp = "Why does this work????";

anotherObject = temp;


this should work .....but
this gives me the following error


Compiling...
Testing.cpp
error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'char *' (or there is no acceptable conversion)



and if i remove the reference to object in operator=()
then it compiles properly

im perplexed a bit.....can u help me out here

phl
January 29th, 2008, 09:48 AM
As per what Paul McKenzie said, the const keyword in the argument of operator=() tells the compiler that the operator function expects a reference to constant object and if I remove the const keyword from the operator=() definition and pass "some string" or an int then it would give an error...ok dat I got ..... but what i dint get is dat......in this case if instead of passing by reference if i define the operator=() with an argument
(object) passed by value then the code compiles and the operator=() is invoked even for
anotherObject = "Why does this work????";



Because it first creates a temporary of abc by calling constructor abc(char*), and then that temporary is passed by value to operator=(abc). Maybe you can run a debugger to see what's happening.


but if the operator is defined as
abc& operator=(abc &ref)
{
return(*this);
}

I get error for anotherObject = "some string";

anotherObject = 8;

is this because im passing "some string" as a literal char?????


In this case, operator=(abc&) expects a reference to an object. However, you cannot pass a reference to a temporary object as an argument. To see my point, try compiling the following code. The compiler will complain that you cannot initialize a non-const reference from a temporary.


int main ()
{
int& i1 = 5; // illegal
const int& i2 = 5; // legal
return 0;
}

phl
January 29th, 2008, 09:53 AM
[...] creates a temporary object and then passes to operator=() a constant reference to that temporary object.

Sorry for nitpicking, but let's not have newbees think about converting objects into references. ;)

Yes, passing is the right choice of word, not converting.

TheCPUWizard
January 29th, 2008, 10:43 AM
Just to add: You can easily avoid this kind of implicit conversion by using the explicit keyword for the constructors. Though not frequently used, it is a very powerful mean to make programs more predictable.

IMHO (and that of Scott Meyers) single argument constructors should ALWAYS have the explicit keyword, unless the design is specifically set up to allow for (and is documented as) providing implicit conversion.

Having the excplicit keyword has been part of our coding standard for years (and part of our automated "lint" like program).

The abount of grief (translate bugs/unexpected operations) that this has saved is tremendous!

DivineBlade
January 29th, 2008, 11:06 AM
thnx a lot everyone for ur active support and timely help.....

it cleared a lotta my doubts........