目录
从理论模型上可以知道,运算符重载可以有两种方法,全局函数方法和成员函数方法。
下面复习一下之前总结过的语法,通过全局函数和成员函数分别实现运算符的重载:
二元运算符重载
二元运算符的定义:
全局函数的实现及调用
void main()
{
Complex c1(1, 2), c2(3, 4);
//1 全局函数法 实现 + 运算符重载
// Complex operator+(Complex &c1, Complex &c2);
Complex c3 = c1 + c2;
c3.printCom();
cout<<"hello..."<<endl;
system("pause");
return ;
}
再看通过全局函数和成员函数分别实现运算符的重载的实现方法:
//全局函数法 实现 + 运算符重载
Complex operator+(Complex &c1, Complex &c2)
{
Complex tmp(c1.a + c2.a, c1.b + c2.b);
return tmp;
}
这就是在上篇博客中所总结的内容,那么现在,开始在这个基础上进行升级!
通过过观察,发现,在我们实际定义的Complex类中,变量“a”和变量“b”应该一般是私有的,但,如果这俩变量是私有的,那私有属性是不能在其类的外部直接访问的,那在编写以全局函数的运算符重载的时候,需要调用这两个私有属性值,那编译器会直接报错,为了解决这个问题,让函数可以访问类的私有函数,所有,这里需要将用到类的私有属性的函数声明成这个类的友元函数才可以!(这也是友元函数的一个应用场景),但千万注意声明时候的数据结构和实现时候的数据结构,必须对应一致,否则会报一大堆的错误(比如,声明的时候是返回一个引用,实现的时候是返回的不是引用,那肯定是会报错的!如下代码就是个错误的,声明的是引用,实现的时候不是引用)
class Complex
{
private:
int a;
int b;
//全局函数 重载+运算符
friend Complex& operator+(Complex &c1, Complex &c2);
}
Complex operator+(Complex &c1, Complex &c2)
{
Complex tmp(c1.a + c2.a, c1.b + c2.b);
return tmp;
}
成员函数的实现及调用
下面看通过成员函数来实现减号运算符的实现:
public:
//成员函数法 实现 -运算符重载
Complex operator-(Complex &c2)
{
Complex tmp(this->a - c2.a, this->b - c2.b);
return tmp;
}
成员函数的调用:
void main()
{
Complex c1(1, 2), c2(3, 4);
//2 成员函数 法 实现 -运算符重载
//c1.operator-(c2);
//Complex operator-(Complex &c2)
Complex c4 = c1 - c2;
c4.printCom();
cout<<"hello..."<<endl;
system("pause");
return ;
}
一元运算符重载
一元运算符重载的定义:
一元运算符重载要比二元运算符重载难些,一元运算符重载一般由前置++,后置++,前置+-,后置+-四个部分组成的。
前置运算
下面进行一个简单案例,用全局函数方法实现一个前置++的demo:
调用:
void main()
{
//前置++操作符 用全局函数实现
++c1;
c1.printCom();
cout<<"hello..."<<endl;
system("pause");
return ;
}
实现,根据业务需要,看返回一个引用还是返回一个成员元素,因为所定义的过程是不断让c1的属性发生变化,如果c1的属性发生变化了,那么返回c1本身就比较合理,故采用返回引用的方式:
//前置++
Complex& operator++(Complex &c1)
{
c1.a++;
c1.b++;
return c1;
}
同时,全局函数所引用的c1中的a,b,两个属性,应该是类中的私有属性,应该把这个定义的全局函数定义成类的友元函数,在类中加入友元函数声明:
class Complex
{
private:
int a;
int b;
//重载 前置++
friend Complex& operator++(Complex &c1);
};
下面再用成员函数实现一个前置--操作符的重载:
调用:
void main()
{
//前置--操作符 成员函数方法
--c1;
c1.printCom();
//Complex& operator++(Complex &c1)
//c1.operator--();
cout<<"hello..."<<endl;
system("pause");
return ;
}
实现:
public:
//前置--
Complex& operator--()
{
this->a --;
this->b --;
return *this;
}
后置运算
下面来进行后置运算符的操作,和前置操作的时候是类似的,但是,对于同一个运算操作,前置跟后置又该如何区分呢?编译器大牛们,在设计的时候,考虑到了这层,所以,有了占位符的语法。如果是后置++,后面会多一个占位符:
//后置++
Complex operator++(Complex &c1, int)
{
//先使用 在让c1加加
Complex tmp = c1;
//return c1;
c1.a ++;
c1.b ++;
return tmp;
}
调用的时候:
//后置++操作符 用全局函数实现
c1++;
c1.printCom();
编译器看见是后置的运算,会自动的调用带有占位符的函数。
剩下的具体运算重载情况,见总体代码部分。
总体代码
dm02_运算符重载的两种方法.cpp
#include <iostream>
using namespace std;
class Complex
{
private:
int a;
int b;
//全局函数 重载+运算符
friend Complex operator+(Complex &c1, Complex &c2);
//重载 前置++
friend Complex& operator++(Complex &c1);
friend Complex operator++(Complex &c1, int);
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(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;
}
};
//全局函数法 实现 + 运算符重载
Complex operator+(Complex &c1, Complex &c2)
{
Complex tmp(c1.a + c2.a, c1.b + c2.b);
return tmp;
}
//前置++
Complex& operator++(Complex &c1)
{
c1.a++;
c1.b++;
return c1;
}
//后置++
Complex operator++(Complex &c1, int)
{
//先使用 在让c1加加
Complex tmp = c1;
//return c1;
c1.a ++;
c1.b ++;
return tmp;
}
/*
全局函数、类成员函数方法实现运算符重载步骤
1)要承认操作符重载是一个函数,写出函数名称
2)根据操作数,写出函数参数
3)根据业务,完善函数返回值(看函数是返回引用 还是指针 元素),及实现函数业务
*/
void main()
{
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 ;
}