关闭

部分运算符只能用友元函数(全局函数)重载 以及链式法则

标签: 友元成员函数classc++
354人阅读 评论(0) 收藏 举报
分类:

有些运算符只能用友元函数(全局函数)重载,无法使用成员函数重载,如

class Complex
{
public:
                 Complex()
                {

                }
                 Complex(int a,int b)
                {
                                 this->a = a;
                                 this->b = b;
                }
                 friend void operator << (ostream & out, Complex C); 
//这里不加引用就会报函数已删除的错误,原函数返回值当左值必须返回一个引用,见图1
protected:
private:
                 int a ;
                 int b ;
};
void operator << (ostream &out, Complex C)
{
                 out << C .a << C.b ;
}

void main ()
{
                 Complex c1 (1, 2);
                 cout << c1 ;
                 system("pause" );
}

图1,不加引用报错:
这里写图片描述

如改成员函数:

则应写为

cout. operator <<(RightOp)

“<<”重载如果想放在成员函数中实现,那就意味着必须作为cout的成员函数,但是cout已经封装好,这里明显是不现实的。

那如果放在Complex成员函数中呢?如:

class Complex
{
public:
                 Complex()
                {

                }
                 Complex(int a,int b)
                {
                                 this->a = a;
                                 this->b = b;
                }
                void operator << (Complex C)
                {

                }
protected:
private:
                 int a ;
                 int b ;
};

我们知道其中隐含的this指针指向的对象如 c1 必须作为左操作数,而在重载函数(void operator << (RightOp))之中他自身又必须作为右操作数,将变成 c1 << c1 这样是不正确的。

所以有些运算符只能用只能用友元函数(全局函数)重载。

引申(链式法则):
上面重载操作时只是采用了简单处理,让其返回void类型

void operator << (ostream &out, Complex C)
{
                 out << C .a << C.b ;
}

但是如果遇到的情况稍微复杂一点,必然会出现一些问题,如:

 cout <<  c1 << "abcd";   

因为上述重载中左操作数为cout,右操作数为c1,而后半部分左操作数为c1,右操作数为“abcd”,虽然我们知道“abcd”常量字符串会返回一个字符串指针,但是此处还可能是跟着各种变量等,所以为了避免反复构造不同的重载,这里我们可以使用链式法则,这样即使后面接 endl 或者其他Complex对象,依然可以正常调用。

为了解决这个问题,我们把问题先拆分成两个简单步骤:

 operator  << (cout ,c1);   //转化为函数调用形式
 cout<< "abcd";

如果想要链式的进行,则使(operator << (cout ,c1) ; )返回cout 即可。

(cout << c1 )<< “abcd”; ====> cout<< “abcd”;

这样即可链式的传递下去。

具体重载方法:

ostream& operator << (ostream &out, Complex C)
{
                 out << C .a << C.b ;    //此处可以不加endl,因为调用时使用 cout <<  c1 << endl; 比较符合习惯   
                 return out ;
}
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:11220次
    • 积分:326
    • 等级:
    • 排名:千里之外
    • 原创:21篇
    • 转载:4篇
    • 译文:0篇
    • 评论:1条