#include <iostream>
using namespace std;
class X {
public:
X& operator=(const X& o)
{
if(this != &o) {
a = o.a;
}
return *this;
}
X() { a = 10; }
void set(int val) { a = val; }
int get() { return a; }
private:
int a;
};
int main(void)
{
X x;
x.set(100);
X p = x;
cout << p.get() << endl;
return 0;
}
If I change a = o.a in the overloaded assignment method,
then I get the following from g++:
g++ -o t t.cpp
t.cpp: In method `X &X::operator= (const X &)':
t.cpp:10: passing `const X' as `this' argument of `int X::get ()'
discards qualifiers
What this is saying is that because my 'o' is of type:
const X&, then get() method discards the qualifier.
But does it really? In addition, if I modify the prototype
of 'get()' to: int get() const, then I have no problem.
Yet why should this matter as the return type of 'get'
is the object type 'int'?
> Consider the following:
>
> #include <iostream>
>
> using namespace std;
>
> class X {
> public:
> X& operator=(const X& o)
> {
> if(this != &o) {
> a = o.a;
> }
> return *this;
> }
> X() { a = 10; }
> void set(int val) { a = val; }
> int get() { return a; }
> private:
> int a;
> };
> int main(void)
> {
> X x;
> x.set(100);
> X p = x;
> cout << p.get() << endl;
> return 0;
> }
>
>
> If I change a = o.a in the overloaded assignment method,
Change to what? I deduce that you meant that you've changed it to
"a=o.get();".
> then I get the following from g++:
> g++ -o t t.cpp
> t.cpp: In method `X &X::operator= (const X &)':
> t.cpp:10: passing `const X' as `this' argument of `int X::get ()'
> discards qualifiers
>
> What this is saying is that because my 'o' is of type:
> const X&, then get() method discards the qualifier.
Yes.
> But does it really? In addition, if I modify the prototype
> of 'get()' to: int get() const, then I have no problem.
> Yet why should this matter as the return type of 'get'
> is the object type 'int'?
Because what a particular class method does is irrelevant, as far as
correctness is concerned. If you have a constant object reference (or a
pointer), you can only invoke the object's constant methods, using that
reference/pointer. What a particular method does or does not bears to
relation on whether the compiler will or will not complain that your code is
correct, according to the C++ language specification.
Declaring "get()" as "get() const" you are telling the compiler (and
the users of your class) that "get()" will not modify the object upon
which that method is called. It is actually good practice to declare
methods which do not modify the objects as const - sometimes it is not
just good practice, but necessary. Read the FAQ about const-
correctness & co.
By the way, there isn't really any need to create an assignment
operator if a shallow, compiler-generated assignment operator will
work just fine.
Anyway, I've recently been taught that protecting a class from self
assignment isn't really a good pick, unless you're implementing your
assignment operator in a weird manner - you're slowing down the
assignment to protect against something which, in this case, isn't
harmful at all, that is, assigning "a" to itself.
These issues should be detailed further, and eventually other posters
will give you better insights on them, but we have had some
discussions about these issues, recently, you could take advantage of
searching the threads about them (search for the copy-swap idiom).
Have good time,
Francesco
--
Francesco S. Carta, hobbyist
http://fscode.altervista.org