Consider the following code segment(something that won't affect the worldview and comprehension can be already omitted.)
class Rectangle
{
private:
double left,top;
double right,bottom;
public:
double length() { return fabs(right-left); }
double heigh(){ return fabs(bottom-top);}
Rectangle operator+(const Rectangle& rival) const;
//.....and so on
}
Now let's look at the definitionof the overloading function of operator +
Rectangle Rectangle::operator+(const Rectangle& rival)const
{
Rectangle temp=*this;
temp.right=this->right+fabs(rival.length());
temp.bottom=this->bottom+fabs(rival.heigh());
return temp;
}
Notice that the argument passed to the function is a const reference to a class Rectangle (const Rectangle& rival). This function will create an temporary variable , initialized to *this,the exact invoking object, and then reset its member datas and return it out. But a doom comes up if we compile the coding and the compiler will complain of these:
error C2662: 'length' : cannot convert 'this' pointer from 'const class Rectangle' to 'class Rectangle &'
error C2662: 'heigh' : cannot convert 'this' pointer from 'const class Rectangle' to 'class Rectangle &'
The two lines causing such error messages are the following contained within operator + function:
temp.right=this->right+fabs(rival.length());
temp.bottom=this->bottom+fabs(rival.heigh());
especially the two member functions evoked by rival:
rival.length();
rival.heigh();
What actually went wrong? Since rival is a const reference ,which means that it cannot be modified ,and even if length() and heigh() do not change anything but the compiler orients them to a damager,or regards them as those having potential trend to changes something expected not to be done so(//因为rival是一个常引用,这意味着它不能被修改,即使其调用的length()和heigh()函数不会修改任何值,但是编译器仍然认为它们会修改常引用的数据,或是认为它们有这个修改的趋势可能), the compiler takes it for granted that throwing error messages to you should be a warrant legitimately. For the sake, you should guarantee functions used by a const object or const reference to an object won't modify anything , that is, be declared as a const one explicitly.
double length() const{return fabs(right-left);}
double heigh() const{return fabs(right-left);}
It's certaily a justification that both const and non-const functions but sharing the same name and arguments coexist within a present class definition:
class
{
public:
double length(){return fabs(right-left);}
double heigh(){return fabs(bottom-top);}
double length()const {return fabs(right-left);}
double heigh()const {return fabs(right-left);}
}
because C++ tells the difference from each other.
Now there is no error and we could make it squarely.
We now , subsequently,pay more attention to the other problem with const qulifier. Suppose there is a member function declared inside the class Rectangle:
Rectangle& operator+=(const Rectangle& rival)const;
Rectangle& Rectangle::operator+=(const Rectangle& rival) const { *this=(*this)+rival; //this line:1st return *this; }
error C2678: binary '=' : no operator defined which takes a left-hand operand of type 'const class Rectangle' (or there is no acceptable conversion)
error C2440: 'return' : cannot convert from 'const class Rectangle' to 'class Rectangle &'
It points out that an operand at the left of binary '=', which is *this, is a 'const class Rectangle' type variable. But how can it be? The key is the const qulifier standing at the endpoint of such a function's head:
Rectangle& Rectangle::operator+=(const Rectangle& rival) const
The const taking up that place tells you that
it is not to modify the object that invokes it,
and here the object is certainly referring to *this.
This declaration is equivalent to make *this to const *this(在成员函数后面加上cosnt表示这个函数不能修改调用该函数的对象,此处也就是对象本身*this,从而等价于将*this在该函数域内声明为cosnt *this类型,故而不能修改*this). Because '=' is also copying function overloaded by compiler by default(or users yourself) and it 's not a const function,so it cannot take a const object as a left-hand operand.Also you are to blame for return a const variable as a non-const type.You can redefine a assignment function as a const member function,or dispose of the const:
Rectangle& Rectangle::operator+=(const Rectangle& rival)
{
*this=(*this)+rival;
return *this;
}