目录
友元函数实现左移右移操作符重载的过程
这里要先强调一下,关于工程实际的应用场景中,运算符重载一般都是使用成员函数来完成的,使用友元函数声明的全局函数的情况是非常少的!但是,但是,但是,在某些场景下,只能使用友元函数来进行实现。
下面提供一个运算符重载的正规案例,通过友元函数来重载左移右移操作符,这个操作只能由友元声明的全局函数来实现,因为用成员函数的话,要重载左移右移操作符,就先找到对应的"cout"对象的,这个类在ostream类中(拿不到源码)中存在,而这个库的内容是不能被轻易修改的。所以,只能用全局函数的方法来实现,这也才是友元函数实现重载的最最真实、独有的场景!
ostream& operator<<(ostream &out, Complex &c1)
{
out<<"12345 生活真是苦"<<endl;
out<<c1.a << " + " << c1.b << "i" << endl;
return out;
}
void main()
{
int a = 10;
Complex c1(1, 2), c2(3, 4);
cout<<a<<endl; //按照数据类型
//1
cout << c1 ;
//2 ostream 类中 添加 成员函数 .operator<<
//ostream
//cout.operator<<(c1);
//2 函数返回值当左值 需要返回一个引用
cout << c1 << "aaddddd";
//
//cout.operator<<(c1) .operator<<("aaddddd");
//void.operator<<("aaddddd");
system("pause");
}
其中,Complex类是上篇博客所定义的类,此处仅作展示,详情见总体代码部分。这个就是通过友元声明的全局函数来进行定义的,声明部分如下:
class Complex
{
private:
int a;
int b;
//friend void operator<<(ostream &out, Complex &c1);
friend ostream& operator<<(ostream &out, Complex &c1);
}
左右移运算符要支持链式编程
再多说一点左右移运算符调用是讲顺序的,要支持链式编程:
在执行以下代码中:
cout << c1 << "aaddddd";
完整的代码执行逻辑实际为:
cout.operator<<(c1) .operator<<("aaddddd");
先调用"cout.operator<<(c1) .operator",再调用"(c1) .operator<<("aaddddd")",实际是执行了两次运算符操作。而如果将原来的左右移运算符重载的函数类型定义成:
void operator<<(ostream &out, Complex &c1)
那么,在执行第一个左右移运算符返回值为void类型,作为下一次左右移运算符的输入,就会报错。所以,在定义左右移运算符的时候返回类型应该为统一的"ostream&"类型。
友元函数重载操作符使用注意点
1. 友员函数重载运算符常用于运算符的左右操作数类型不同的情况
2. 其他
-
在第一个参数需要隐式转换的情形下,使用友员函数重载运算符是正确的选择
-
友员函数没有 this 指针,所需操作数都必须在参数表显式声明,很容易实现类型的隐式转换
-
C++中不能用友员函数重载的运算符有:
= () [] ->
总体代码
dm03_运算符重载正规的写法.cpp
#include <iostream>
using namespace std;
/*
class ostream
{
};
*/
class Complex
{
private:
int a;
int b;
//friend void operator<<(ostream &out, Complex &c1);
friend ostream& operator<<(ostream &out, Complex &c1);
public:
Complex(int a=0, int b=0)
{
this->a = a;
this->b = b;
}
void printCom()
{
cout<<a<<" + " << b << "i" <<endl;
}
public:
//实现 + 运算符重载
Complex operator+(Complex &c2)
{
Complex tmp(a + c2.a, b + c2.b);
return tmp;
}
//前置++
Complex& operator++()
{
a++;
b++;
return *this;
}
//后置++
Complex operator++(int)
{
//先使用 在让c1加加
Complex tmp = *this;
//return c1;
this->a ++;
this->b ++;
return tmp;
}
//成员函数法 实现 -运算符重载
Complex operator-(Complex &c2)
{
Complex tmp(this->a - c2.a, this->b - c2.b);
return tmp;
}
//前置--
Complex& operator--()
{
this->a --;
this->b --;
return *this;
}
//后置--
Complex operator--(int)
{
Complex tmp = *this;
this->a--;
this->b--;
return tmp;
}
};
void main31()
{
Complex c1(1, 2), c2(3, 4);
//1 全局函数法 实现 + 运算符重载
// Complex operator+(Complex &c1, Complex &c2);
Complex c3 = c1 + c2;
c3.printCom();
//2 成员函数 法 实现 -运算符重载
//c1.operator-(c2);
//Complex operator-(Complex &c2)
Complex c4 = c1 - c2;
c4.printCom();
//前置++操作符 用全局函数实现
++c1;
c1.printCom();
//前置--操作符 成员函数方法
--c1;
c1.printCom();
//Complex& operator++(Complex &c1)
//c1.operator--();
//后置++操作符 用全局函数实现
c1++;
c1.printCom();
//后置--操作符 用成员函数实现
c1--;
c1.printCom();
//c1.operator--()
cout<<"hello..."<<endl;
system("pause");
return ;
}
/*
void operator<<(ostream &out, Complex &c1)
{
out<<"12345 生活真是苦"<<endl;
out<<c1.a << " + " << c1.b << "i" << endl;
}
*/
ostream& operator<<(ostream &out, Complex &c1)
{
out<<"12345 生活真是苦"<<endl;
out<<c1.a << " + " << c1.b << "i" << endl;
return out;
}
void main()
{
int a = 10;
Complex c1(1, 2), c2(3, 4);
cout<<a<<endl; //按照数据类型
//1
cout << c1 ;
//2 ostream 类中 添加 成员函数 .operator<<
//ostream
//cout.operator<<(c1);
//2 函数返回值当左值 需要返回一个引用
cout << c1 << "aaddddd";
//
//cout.operator<<(c1) .operator<<("aaddddd");
//void.operator<<("aaddddd");
system("pause");
}