您的位置:首页 > 其它

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

2016-03-31 22:22 731 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: