前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >C++ 运算符重载的基本概念

C++ 运算符重载的基本概念

作者头像
小林coding
发布2020-03-31 16:31:18
发布2020-03-31 16:31:18
1K00
代码可运行
举报
文章被收录于专栏:小林coding小林coding
运行总次数:0
代码可运行

1

运算符重载的需求

C++ 预定义的运算符,只能用于基本数据类型的运算:整型、实型、字符型、逻辑型等等,且不能用于对象的运算。但是我们有时候又很需要在对象之间能用运算符,那么这时我们就要重载运算符,使得运算符能用于对象之间的运算。

比如,在数学上,两个复数可以直接进行+、-等运算,但在C++中,直接将+或-用于复数对象是不允许的。有时会希望,让对象也能通过运算符进行运算。这样代码就更简洁,也容易理解。

例如:

complex_a 和 complex_b 是两个复数对象,求两个复数的和,希望的能直接写成:complex_a + complex_b

这时我们就需要对+号运算符进行重载。

2

运算符重载的形式

运算符重载的实质就是函数重载,可以重载为普通函数,也可以重载为成员函数。运算符重载的基本形式如下:

代码语言:javascript
代码运行次数:0
复制
返回值类型 operator 运算符(形参表)
{
    ...
}

下面举个例子,实现对复数对象的+-运算符重载:

代码语言:javascript
代码运行次数:0
复制
class Complex // 复数类
{
public:
// 构造函数,如果不传参数,默认把实部和虚部初始化为0
Complex(double r = 0.0, double i = 0.0):m_real(r),m_imag(i) {  }

// 重载-号运算符,属于成员函数
Complex operator-(const Complex & c)
{
// 返回一个临时对象
return Complex(m_real - c.m_real, m_imag - c.m_imag);
}

// 打印复数
void PrintComplex()
{
cout << m_real << "," << m_imag << endl;
}
    
    // 将重载+号的普通函数,定义成友元函数
    // 目的是为了友元函数能访问对象的私有成员
    friend Complex operator+(const Complex &a, const Complex &b);
    
private:
double m_real;  // 实部的值
double m_imag;  // 虚部的值
};

// 重载+号运算符,属于普通函数,不是对象的成员函数
Complex operator+(const Complex &a, const Complex &b)
{
// 返回一个临时对象
return Complex(a.m_real + b.m_real, a.m_imag + b.m_imag);
}

int main()
{
Complex a(2,2);
Complex b(1,1);
Complex c;

c = a + b; // 等价于c = operator+(a,b)
c.PrintComplex();

c = a - b; // 等价于 c = a.operator-(b)
c.PrintComplex();

return 0;
}

输出结果:

代码语言:javascript
代码运行次数:0
复制
3,3
1,1

从上面的例子中,我们可以知道重载为成员函数和普通函数的区别了:

  • 重载为成员函数时,参数个数为运算符目数减一。如:c = a - b;等价于c = a.operator-(b)
  • 重载为普通函数时,参数个数为运算符目数。如:c = a + b; 等价于c = operator+(a,b)

在上面的代码中,我把重载+号运算符的普通函数,在Complex复数类中定义成了友元函数,目的是为了友元函数能访问对象的私有成员,否则会编译报错。

3

加减运算符的返回值和参数表

这里还有个值得思考的问题:

  • 为什么重载-号和+号运算符函数的返回类型是Complex对象而不是Complex &呢?
  • 为什么重载-号和+号的运算符函数的参数表是const Complex & c常引用类型而不是Complex c呢?
代码语言:javascript
代码运行次数:0
复制
// 重载-号运算符,属于成员函数
Complex Complex::operator-(const Complex & c)
{
// 返回一个临时对象
return Complex(m_real - c.m_real, m_imag - c.m_imag);
}

首先先说一下参数表为什么是const Complex & c常引用类型,首先如果参数表如果普通的对象形式Complex c,那么在入参的时候,就会调用默认的赋值(拷贝)构造函数,产生了一个临时对象,这会增大开销,所以就采用引用的方式,同时又为了防止引用的对象被修改,所以就定义成了const Complex & c常引用类型。

再来说一下返回值为什么是普通Complex对象,因为本次 - 号和 + 号运算符的函数执行之后,需要返回一个新的对象给到左值。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小林coding 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档