The resolution of ERROR C2662: cannot convert 'this' pointer from "const Class-Type" to "Class&"

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;

whose definition is given below:

</pre><pre name="code" class="cpp">Rectangle& Rectangle::operator+=(const Rectangle& rival) const 
{
	*this=(*this)+rival;  //this line:1st
	return *this;
}


 When compiling this code, there is a ERROR Message: 

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)<strong><span style="color:#cc0000;"> const</span></strong> 
The const taking up that place tells you thatit 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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章