C++学习26 运算符重载的概念和语法

所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载(Operator Overloading)也是一个道理,同一个运算符可以有不同的功能。

实际上,我们已经在不知不觉中使用了运算符重载。例如,"+"号可以对不同类型(int、float 等)的数据进行加法操作;"<<"既是位移运算符,又可以配合 cout 向控制台输出数据。C++已经对这些运算符进行了重载。

C++ 也允许程序员自己重载运算符,这给我们带来了很大的便利。

下面的代码定义了一个复数类,通过运算符重载,用"+"号实现了复数的加法运算:

#include <iostream>
using namespace std;
class complex{
private:
    double real;  //实部
    double imag;  //虚部
public:
    complex(): real(0.0), imag(0.0){ }
    complex(double a, double b): real(a), imag(b){ }
    complex operator+(const complex & A)const;
    void display()const;
};
//运算符重载
complex complex::operator+(const complex & A)const{
    complex B;
    B.real = real + A.real;
    B.imag = imag + A.imag;
    return B;
}
void complex::display()const{
    cout<<real<<" + "<<imag<<"i"<<endl;
}
int main(){
    complex c1(4.3, 5.8);
    complex c2(2.4, 3.7);
    complex c3;
    c3 = c1 + c2;
    c3.display();

    return 0;
}

上面的代码定义了一个复数类,real 表示实部,imag 表示虚部,第11行声明了运算符重载,第16行进行了定义。认真观察这两行代码,可以发现和函数重载非常类似。

运算符重载的方式就是定义一个函数,在函数体内实现想要的功能,当用到该运算符时,编译器会自动调用这个函数。也就是说,运算符重载是通过函数定义实现的,它本质上是函数重载。

运算符重载的格式为:

返回值类型 operator 运算符名称 (形参表列){
    //TODO:
}

operator 是关键字,专门用于定义重载运算符的函数。例如,要在全局范围内重载"+",实现复数加法运算,可以这样来定义:

complex operator+(const complex &A, const complex &B){
    complex C;
    C.real = A.real + B.real;
    C.imag = A.imag + B.imag;
    return C;
}

细心观察就可以发现,函数名由 operator 和操作符组成,上面的”operator+“就是函数名。重载运算符的函数除了函数名有特定的格式,其他地方和普通函数没有区别。

上面的例子中,我们在类 Complex 中重载了运算符"+",该重载只对 Complex 对象有效。当执行c3 = c1 + c2;语句时,编译器检测到"+"号左边("+"号具有左结合性)是一个 Complex 对象,就会调用运算符重载函数,该语句会被转换为:

c1.operator+(c2);

很明显是一个函数调用。

上面的运算符重载还可以有更加简练的定义形式:

complex complex::operator+(const complex & A)const{
    return complex(real+A.real, imag+A.imag);
}

return 语句中的complex(real+A.real, imag+A.imag)会创建一个临时对象,它没有对象名,是一个匿名对象。在创建临时对象过程中调用构造函数,return 语句将该临时对象作为函数返回值。

虽然重载运算符所实现的功能完全可以用函数替代,但运算符重载使得程序的书写更加人性化,易于阅读。运算符被重载后,原有的功能仍然保留,没有丧失或改变。通过运算符重载,扩大了C++已有运算符的功能,使之能用于类对象。

重载运算符的规则

C++对运算符重载做了诸多的限制。

1) 首先,并不是所有的运算符都可以重载。能够重载的运算符包括:
+  -  *  /  %  ^  &  |  ~  !  =  <  >  +=  -=  *=  /=  %=  ^=  &=  |=
<<  >>  <<=  >>=  ==  !=  <=  >=  &&  ||  ++  --  ,  ->*  ->  ()  []
new  new[]  delete  delete[]

上述操作符中,[] 是下标操作符,() 是函数调用操作符。自增自减操作符的前置和后置形式都可以重载。长度运算符”sizeof“、条件运算符”: ?“、成员选择符”.“、对象选择符”.*“和域解析操作符”::“不能被重载。

上述操作符中,[] 是下标操作符,() 是函数调用操作符。自增自减操作符的前置和后置形式都可以重载。长度运算符”sizeof“、条件运算符”: ?“、成员选择符”.“、对象选择符”.*“和域解析操作符”::“不能被重载。

2) 重载不能改变运算符的优先级和结合性。假设上一节的 complex 类中重载了"+"号和"*"号,那么下面代码中:

int main(){
    complex c1,c2,c3,c4;
    c4 = c1 + c2 * c3;
    return 0;
}

c4 = c1 + c2 * c3;语句等同于c4 = c1 + ( c2 * c3 ) ;,乘法的优先级仍然高于加法,而且它们也仍然是二元运算符。

3) 重载不会改变运算符的用法,例如"+"号总是出现在两个操作数之间,重载后也必须如此。

4) 重载运算符的函数不能有默认的参数,否则就改变了运算符操作数的个数,这显然是错误的。

时间: 2024-10-12 10:28:19

C++学习26 运算符重载的概念和语法的相关文章

java学习(二)基础概念、语法

对象 类的实例(通俗点讲,new出来的玩意好像都是对象?初学者的感觉,不造对错啊,有大神给我解释下可以啊) 类 class嘛,模板嘛,可以给对象实例的嘛 方法 行为,学编程的,方法,这玩意心里都懂吧,用前端的话,function嘛 实例变量 每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定. (实例嘛就是对象嘛,就是对象的变量嘛) 语法 类名首字母大写,多个单词每个单词都首字母大写 方法名首字母小写,多个单词除了首字母其他单词首字母大写 大小写区分 所有的Java 程序由public

运算符重载(作为成员函数)

运算符重载---基本概念 C++程序设计 郭炜 刘家瑛 1 #include<iostream> 2 using namespace std; 3 class Complex{ 4 private: 5 double real; 6 double imaginary; 7 public: 8 Complex(double a=0.0,double b=0.0) : real(a),imaginary(b) {}//初始化 9 ~Complex(){} 10 Complex operator+(

运算符重载(作为普通函数)

运算符重载---基本概念 C++程序设计 郭炜 刘家瑛 1 #include<iostream> 2 using namespace std; 3 class Complex{ 4 public: 5 double real; 6 double imaginary; 7 Complex(double a=0.0,double b=0.0) : real(a),imaginary(b) {}//初始化 8 ~Complex(){} 9 void print(); 10 }; 11 Complex

Python——运算符重载(1)

运算符重载 关键概念: 1.运算符重载让类拦截常规的Python运算. 2.类可重载所有的Python表达式运算符. 3.类也可重载打印.函数调用.属性点号运算等内置运算. 4.重载使类实例的行为像内置类型. 5.重载是通过特殊名称的类方法来实现的. 运算符重载只是意味着在类方法中拦截内置的操作--当类的实例出现在内置操作中,Python自动调用你的方法,并且你的方法的返回值变成了相应操作的结果. =================================================

Python面向对象运算符重载

运算符重载的概念如下: 运算符重载让类拦截常规的Python运算: 类可重载所有Python表达式运算符: 类也可重载打印.函数调用.属性点号运算等内置运算: 重载是类实例的行为想内置类型: 重载是通过提供特殊名称的类方法来实现的: 常见的运算符重载方法 方法 重载 调用 __init__ 构造函数 对象建立:X = Class(args) __del__ 解析函数 X对象收回 __add__ 运算符+ 如果没有__iadd__,X+Y,X+=Y __or__ 运算符或 如果没有__ior__

初步理解[函数重载]和[运算符重载]&#183;转

作者:黄兢成链接:https://www.zhihu.com/question/23407045/answer/24543450来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 很多疑问都是想不通那东西具体用于什么地方. 比如我初学 C++ 时,早就知道指针实际就是某个变量的地址,就是不知道具体怎么用.这感觉就仿佛学数学,我知道某定理,也知道某定理的证明是对的,但我就是不知道这东西有什么用.直到学数据结构,接触到链表,才突然明白指针. 所以语法只是初步,更重要的是要

7Python全栈之路系列之面向对象运算符重载

Python全栈之路系列之面向对象运算符重载 运算符重载的概念如下: 运算符重载让类拦截常规的Python运算: 类可重载所有Python表达式运算符: 类也可重载打印.函数调用.属性点号运算等内置运算: 重载是类实例的行为想内置类型: 重载是通过提供特殊名称的类方法来实现的: 常见的运算符重载方法 方法 重载 调用 __init__ 构造函数 对象建立:X = Class(args) __del__ 解析函数 X对象收回 __add__ 运算符+ 如果没有__iadd__,X+Y,X+=Y _

加法运算符重载为从成员函数执行过程

今天学习了运算符重载函数,测试了复数类加减运算符的重载,不明白运算符重载函数的执行过程,重点探究一下: 首先贴出源代码 // example_1_2_cl_dt_fushujiajian.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using namespace std; class complex { public: complex(double r=0.0,double i=0.0){re

对运算符重载和友元函数的例子

以下是博主在学习完运算符重载和友元函数后编写的一个例子,实现一个复数的基本运算.定义的头文件: /****************************************************************** complex.h Defination of the complex ******************************************************************/ #ifndef _complex_ #define _com