一. operator=返回值及形参的讲究:
1.string& string::operator=(const string& rhs){
return *this;
}
在这种情况下 ,赋值操作符的重载可以面对的几种情况:
①. string s1;
s1 = "Hello";
此时编译器会做如下处理:
const string __temp("Hello");
s1.operator=(__temp);
② string s1,s2;
s2 = s1 = "Hello";
实际转换为:
const string __temp("Hello");
s2.operator=(s1.operator=(__temp));
③ string s1,s2,s3;
(s2=s1="Hello")=(s3="Hello_world");
实际转换为:
const string __temp("Hello_world");
const tring __temp1("Hello");
(s2.operator=(s1.operator(__temp1))).operator=(s3.operator=(__temp));
分步解析时可以看出:
a. s3.operator=(__temp);
b. s1.operator=(__temp1);
c. s2.operator=(s1);//这里讲string&实参转换为const string&形参是合法的
d. s2.operator=(s3);//同上
2. string& string::operator=(string & rhs){
return *this;
}以及
string& string::operator=(string& rhs){
return rhs;
}
当遇到
string s1;
s1 = "Hello";
这种形式的调用时,将会编译失败,原因为编译器会为"Hello"的C字符串生成一个const临时变量,而将const临时变量作为实参传递给非const的形参时,
编译失败。
3. string& string::operator=(const string & rhs){
return rhs;
}以及
const string& operator=(const string &rhs){
return *this;
}
当遇到
string s1,s2,s3;
(s2 = s1) = s3;这种情况时,会编译失败,失败原因是将一个值赋予const变量。
因为(s2 = s1)返回的结果是一个const限定后的变量。
二. 在继承层次中的复制控制:
当一个派生类从基类中继承时,需要显示地调用基类的operator=函数,即是该函数时编译器为基类自动合成的。
例如:
calss Base{
public:
....
Base & operator=(const Base& rhs);
private:
int x;
};
Base & Base::operator=(const Base& rhs){
(*this).x = rhs.x;
return *this;
}
class Derived : public Base{
public:
....
Derived& operator=(const Derived& rhs);
private:
int y;
};
Derived & Derived::operator=(const Derived& rhs){
static_cast<Base&>(*this) = rhs;
*this.y = rhs.y
}
让我们来看看编译器此时会做什么:
由于我们明确调用了static_cast<Base&>将*this转化为一个Base的引用,因而此时会获取*this即派生类对象的基类子对象,
并调用Base::operator=(rhs),而rhs是一个派生类对象,因而编译器又会再一次地将rhs转化为一个基类的引用,即做如下转化:
const Base& __temp1 = static_cast<Base&>(*this);//实时上不需要生成此临时对象,为了便于理解将其列出。
const Base& __temp2 = static_cast<Base&>rhs;
__temp1.operator=(__temp2);
进而,我们可以在对Derivedl类对象赋值的同时控制其Base类子对象的赋值。