典型的双目操作符重载
运算类双目操作符
一.操作数与表达式
•左右操作数均可为左值或右值
–Complex lv (1, 2);
Complex const rv (3, 4);
lv + rv;
rv + lv;
•表达式的值必须是右值
–Complex a (1, 2), b (3, 4), c (5, 6);
(a + b) = c; // 错误
二.成员函数
•常函数以支持右值型左操作数,常参数以支持右值型右操作数,常返回值以支持右值型表达式的值
–class Complex
{
public:
Complex const operator+ ( Complex const& rhs) const
{
return Complex (m_r + rhs.m_r, m_i + rhs.m_i);
}
};
三.全局函数
•常第一参数以支持右值型左操作数,常第二参数以支持右值型右操作数,常返回值以支持右值型表达式的值
–Complex const operator+ (Complex const& lhs, Complex const& rhs)
{
return Complex (lhs.m_r + rhs.m_r, lhs.m_i + rhs.m_i);
}
•为了在一个全局操作符函数中直接访问其操作数类型的私有及保护成员,同时又不破坏其操作数类型的封装性,可以将该操作符函数声明为其操作数类型的友元
–friend Complex const operator+ (Complex const&, Complex const&);
友元
一.friend
•可以通过friend关键字,把一个全局函数、另一个类的成员函数或者另一个类整体,声明为某个类的友元
–class A
{
friend void foo (void);
friend void B::bar (void) const;
friend class C;
–其中A称为全局函数foo、成员函数B::bar和类C的授权类
–全局函数foo、成员函数B::bar和类C称为A的友元函数和友元类
二.友元特权
•友元拥有访问授权类任何非公有成员的特权
三.友元声明
•友元声明可以出现在授权类的公有、私有或者保护等任何区域,且不受访问控制限定符的约束
–class A
{
friend void foo (A& a);
public:
friend void bar (A const* a);
protected:
friend void hum (void);
private:
int m_pri;
};
–void foo (A& a) { a.m_pri++; }
void bar (A const* a) { cout << a->m_pri << endl; }
void hum (void) { A a; a.m_pri = 0; }
四.友元非成员
•友元不是成员,即便将其定义在授权类的内部,其作用域也不属于授权类,当然也不拥有授权类的this指针
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
–class Integer
{
public:
void set (int n) { m_n = n; } // 成员
friend void set (Integer& i, int n) { i.m_n = n; } // 友元
int get (void) const { return m_n; } // 成员
friend int get (Integer const& i) { return i.m_n; } // 友元
private:
int m_n;
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
•因为不隶属于同一个作用域,友元和成员也不可能构成重载
五.友元操作符
•双目操作符函数常被声明为其左操作数的成员,同时也是其右操作数的友元,这样它就可以毫无障碍地访问左右两个操作数的非公有成员,而不对封装构成太大影响
–class Mail
{
friend void Mbox::operator<< (Mail const&) const;
private:
string m_title, m_content;
};
–class Mbox
{
void operator<< (Mail const& mail) const { ... mail.m_title ... mail.m_content ... }
};
–Mbox mbox ("minwei@tarena.com.cn");
Mail mail ("通知", "今天18:00召开教学例会");
mbox << mail;
典型的单目操作符重载
运算类单目操作符重载
一.操作数与表达式
•操作数为左值或右值
–Complex lv (1, 2);
Complex const rv (3, 4);
-lv;
~rv;
•表达式的值必须是右值
–Complex a (1, 2), b (3, 4);
-a = b; // 错误
二.成员函数
•常函数以支持右值型操作数,常返回值以支持右值型表达式的值
–class Complex
{
public:
Complex const operator- (void) const
{
return Complex (-m_r, -m_i);
}
};
三.全局函数
•常参数以支持右值型操作数,常返回值以支持右值型表达式的值
–Complex const operator- (Complex const& opd)
{
return Complex (-opd.m_r, -opd.m_i);
}