操作符重载 正规写法(链式编程+友元函数应用场景)
- 正规写法
- 值得注意的点
- 总结
阅读之前注意:
本文阅读建议用时:30min
本文阅读结构如下表:
项目 | 下属项目 | 测试用例数量 |
---|---|---|
正规写法 | 无 | 1 |
值得注意的点 | 无 | 0 |
总结 | 无 | 0 |
正规写法
从上一篇博客我们知道了怎么重载C++中的输出操作符“<<”,那些代码虽然很好的体现了技术的演变过程,但却不够严谨和规范。从严谨性来说,缺点在于无法实现链式编程,即无法使用“cout<<自定义对象1<<自定义对象2<<endl
”这样的语句;从规范性来说,变量设置为public并不合理(应该设置为私有属性private以保护内部数据)。
因此,现在我们按照正规写法来,首先,像“+”号、“++”号等的重载实现,可以在类的内部实现,就应该在类的内部实现,而不应该滥用全局函数,那什么时候采用全局函数呢?自然就是那些无法在类的内部实现重载的操作符了,输出操作符"<<“即是很好的例子,因为我们无法去修改cout这个类,所以采用全局函数来重载”<<";其次,当把类的内部变量设置为private时,产生了一个问题,全局函数无法访问私有变量,解决方法就是友元函数声明。
以下是完整演示代码1:
#include"iostream"
using namespace std;
class A
{
public:
A(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
}
void print()
{
cout << "a" << this->a << " b" << this->b << endl;
}
A operator+(A &A2)
{
A tmp;
tmp.a = this->a + A2.a;//注意:私有是针对类而言的
tmp.b = this->b + A2.b;
return tmp;
}
A &operator++()//前置++
{
this->a++;
this->b++;
return *this;
}
A operator++(int)//后置++
{
A tmp = *this;//调用拷贝构造函数
this->a++;
this->b++;
return tmp;//返回临时对象,类做返回值会调用拷贝构造函数
}
//friend void operator<<(ostream &out,A &a1);//非链式编程
friend ostream& operator<<(ostream &out, A &a1);//友元函数声明+链式编程
private:
int a;
int b;
};
ostream &operator<<(ostream &out,A &a1)//用全局函数实现操作符重载
{
out << "a" << a1.a << " b" << a1.b << endl;
return out;
}
void main1()//测试场景1
{
A a1(1, 2), a2(3, 4);
++a1;
a1.print();
cout << a1;
cout << a1++;
cout << ++a1;
A a3 = a1 + a2;
cout << a3;
//没有办法在cout类里面添加函数operator<<,只能通过全局函数实现
//cout.operator<<(a3);
system("pause");
}
void main()//测试场景
{
A a1(1, 2), a2(3, 4);
cout << a1 << a2 << endl;//链式编程
//函数返回值当左值的情况,需要返回一个对象的引用
//operator<<(cout, a1);
system("pause");
}
值得注意的点
以上代码为了实现链式编程,即函数返回值当左值的情况,需要返回一个对象的引用。
总结
本篇博客的核心是:操作符重载如果无法在类的内部实现,则应通过友元函数声明,用全局函数实现重载。
如果本文对你有帮助,不如请我一罐可乐吧 🍼
代码基于王保明先生的讲课内容. ↩︎