本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这是本文档旧的修订版!
第 12 章笔记
运算符重载是指在 C++ 中基于 operator
关键字引入对运算符的重载。经过重载的运算符可以被视作函数,典型的结构(以减法为例):
return Type + operator - + (parameter list)
operator()
,其他重载的运算符都不能设置默认参数运算符重载可以以成员函数或非成员函数的方式来实现:
*this
作为第一个 operand==
与 ⇔
并不遵循此例
// 非成员函数重载
Str operator+ (Str x, Str y)
{
Str z;
z.x = x.x + y.x;
return z;
}
// 成员函数重载
Str operator+(Str rhs)
{
Str z;
//x imply this->x
z.x = x + rhs.x;
return z;
}
=
,()
, →
,转型运算符&&
,||
,,
。这类运算符往往需要维护特定的求值顺序,而
指可以左右算子互换位置的运算符(比如 +
,==
等)。对称性运算符需要被设计为非成员重载,是因为:
class Str
{
public:
Str(int x) :val(x) {}
Str operator+ (const Str& rhs) {...}
private:
int val;
};
int main(int argc, char const *argv[])
{
Str myStr1(2);
// 可以进行正常运算,4 对应 rhs, 可以通过 Str 的构造函数转化为 Str 类型
Str myRetStr =myStr1 + 4;
// 无法正常进行运算,4 不是 Str (this指向的) 类型
Str myRetStr = 4 + myStr1;
return 0;
}
this
的匹配影响,上述例子中的 4
则可以在函数匹配的过程中进行隐式转换。friend
,否则无法访问私有数据 移位运算符必须重载为非成员函数。这是因为 C++ 中移位运算符有一个更重要的应用:输入输出流运算符。输入输出流运算符一般的格式为:
StreamObjReference << Object;
这种情况下,成员函数版本无法支持该功能。
// 简单的输出流重载实现
// 需要声明为友元函数
std::ostream& operator << (std::ostream& ostr, const Str &output)
{
ostr << output.val;
return ostr;
}
// 简单的实现
Str& Str::operator= (const Str& rhs)
{
if(this != &rhs)
{
val = rhs.val;
}
return *this;
}
该运算符重载用于模拟下标操作。典型的应用是 std::vector
。需要考虑的问题有:
主要的问题在第二个子问题上:
ObjA[0] = ObjB
这种形式的运算进行处理。因此,下标运算的返回结果一定是左值,也就是对象的引用。const
时,这种写入的操作应该被侦测并禁止。因此,我们需要一个专门的 const 实现版本来处理该情况。
// 简单的实现,基于 String 的下标运算重载
class StrVec {
public:
std::string& operator[](std::size_t n)
{ return elements[n]; }
// const 版本
const std::string& operator[](std::size_t n) const
{ return elements[n]; }
private:
std::string* elements; // pointer to the first element in the array
};