参考:http://www.runoob.com/cplusplus/cpp-overloading.html
https://www.cnblogs.com/CaiNiaoZJ/archive/2011/08/12/2136598.html

前言:

运算符重载和函数重载体现了面向对象技术的多态性。多态性机制不仅增加了面向对象软件系统的灵活性,进一步减少了冗余信息,而且显著提高了软件的可重用性和可扩充性。
    从实现的角度来讲,多态性可以划分为两类:编译时的多态性和运行时的多态性。在C++语言中,编译时的多态性主要是通过函数重载和运算符重载实现的。
    本文主要讲的是编译时多态,因为编译时多态主要是通过函数重载和运算符重载实现的。
运行时多态之后再讲。

C++允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。

一、C++ 中的函数重载

概念

重载:是指运行存在多个同名函数,而这些函数的参数列表不同(参数个数、类型、顺序),不能使用返回值作为区分。
关键词:同一作用域内,具有相同函数名,不同参数列表

原理

重命名机制(name mangling):
编译器根据函数不同的参数表,对同名函数的名称进行函数修饰,从而这些同名函数就成为了不同的函数(至少对于编译器来说是这样的)。该过程在编译器间就已经确定了,也就是说在编译期就绑定了(早绑定)。

区分

C语言是不支持函数重载的,这里涉及另外一个知识点:C++在兼容C时的extern "C"的用法。

代码实例

#include<iostream>
using namespace std;void print(int i)
{cout<<"print a integer :"<<i<<endl;
}void print(string str)
{cout<<"print a string :"<<str<<endl;
}int main()
{print(12);print("hello world!");return 0;
}

二、C++ 中的运算符重载

2.0 使用全局函数进行运算符重载(数据成员为public属性)

C++就为运算符重载提供了一种方法,即运算符重载函数。其函数名字规定为operator后紧跟重载运算符。比如:operator+(),operator*()等。现在我们给出一个加法运算符的重载函数用于完成复数的加法运算:

#include <iostream>
using namespace std;class Complex //复数类
{public:double real;//实数double imag;//虚数Complex(double real=0,double imag=0){this->real=real;this->imag=imag;}
};Complex operator+(Complex com1,Complex com2)//运算符重载函数
{return Complex(com1.real+com2.real,com1.imag+com2.imag);
}int main()
{Complex com1(10,10),com2(20,20),sum;sum=com1+com2;//或sum=operator+(com1,com2)cout<<"sum的实数部分为: "<<sum.real<<endl;cout<<"sum的虚数部分为: "<<sum.imag<<"i"<<endl;return 0;
}

输出:

sum的实数部分为: 30
sum的虚数部分为: 30i

上述示例中的运算符重载函数是不属于任何的类,是全局的函数。因为在Complex类(复数类)中的数据成员是公有的性质,所以运算符重载函数可以访问。但如果定义为私有的呢,那该怎么办。其实,在实际的运算符重载函数声明当中,有两种方法:
定义其为要操作类的成员函数或类的友元函数

2.1 运算符重载函数作为类的友元函数的形式:

友元函数重载双目运算符(有两个操作数,通常在运算符的左右两则),参数表中的个数为两个。若是重载单目运算符(只有一个操作数),则参数表中只有一参数。

  class 类名{friend 返回类型 operator运算符(形参表);}类外定义格式:返回类型 operator运算符(参数表){函数体}
1) 友元函数重载双目运算符(+)
#include <iostream>
using namespace std;class Complex //复数类
{//私有数据
private:double real;//实数double imag;//虚数
public:    Complex(double real=0,double imag=0){this->real=real;this->imag=imag;}//友元函数重载双目运算符friend Complex operator+(Complex com1,Complex com2);void showSum();
};Complex operator+(Complex com1,Complex com2)//运算符重载函数
{return Complex(com1.real+com2.real,com1.imag+com2.imag);
}void Complex::showSum()
{if(imag>=0){cout<<real<<"+"<<imag<<"i"<<endl;}else{cout<<real<<imag<<"i"<<endl;}}
int main()
{Complex com1(10,10),com2(20,20),sum;sum=operator+(com1,com2);//或  sum=com1+com2sum.showSum();return 0;
}
2) 友元函数重载单目运算符(++):

#include <iostream>
using namespace std;class Point//坐标类
{private:int x;int y;public:Point(int x,int y){this->x=x;this->y=y;}friend void operator++(Point& point);//友元函数重载单目运算符++void showPoint();
};void operator++(Point& point)//友元运算符重载函数
{++point.x;++point.y;
}void Point::showPoint()
{std::cout<<"("<<x<<","<<y<<")"<<std::endl;
}int main()
{Point point(10,10);++point;//或operator++(point)point.showPoint();//输出坐标值return 0;
}

输出

(11,11)
2.2 运算符重载函数作为类的成员函数的形式:

对于成员函数重载运算符而言,双目运算符的参数表中仅有一个参数,而单目则无参数。同样的是重载,为什么和友元函数在参数的个数上会有所区别的。原因在于友元函数,没有this指针。

 class 类名{返回类型 operator 运算符(形参表);}类外定义格式:返回类型 类名:: operator 运算符(形参表){函数体;}
1) 成员函数重载双目运算符(+):
#include <iostream>
using namespace std;class Complex //复数类
{//私有数据
private:double real;//实数double imag;//虚数
public:    Complex(double real=0,double imag=0){this->real=real;this->imag=imag;}//成员函数重载双目运算符Complex operator+(Complex com1);void showSum();
};Complex Complex::operator+(Complex com1)
{return Complex(real+com1.real,imag+com1.imag);
}void Complex::showSum()
{if(imag>=0){cout<<real<<"+"<<imag<<"i"<<endl;}else{cout<<real<<imag<<"i"<<endl;}}
int main()
{Complex com1(10,10),com2(200,200),sum;sum=com1+com2;//或  sum=com1.operator+(com2);sum.showSum();return 0;
}
2)成员函数重载单目运算符(++)

#include <iostream>
using namespace std;class Point//坐标类
{private:int x;int y;public:Point(int x,int y){this->x=x;this->y=y;}void operator++();//成员函数重载单目运算符++void showPoint();
};void Point::operator++()//成员运算符重载函数
{++x;++y;
}void Point::showPoint()
{std::cout<<"["<<x<<","<<y<<"]"<<std::endl;
}int main()
{Point point(10,10);++point;//或operator++(point)point.showPoint();//输出坐标值return 0;
}

输出

[11,11]

三、重载输出运算符<<

#include<iostream>
using namespace std;class People{public:People(int id,int pwd):m_id(id),m_pwd(pwd){}~People(){}friend ostream& operator<< (ostream &os,People p);
private:int m_id;int m_pwd;
};
ostream& operator << (ostream &os, const People p){os<<"your id is:"<<p.m_id<<" and password is:"<<p.m_pwd<<endl;return os;
}int main() {People a(1,123);People b(2,456);cout << a<<b;}
输出:
your id is:1 and password is:123
your id is:2 and password is:456

注:
输出运算符的第一个形参是非常量ostream对象的引用。之所以非常量是因为向流写入内容会改变其状态;而该形参是引用是因为我们无法直接复制一个ostream对象。
第二个形参一般是常量引用,该常量是我们要打印的类类型,之所以是常量是因为我们打印一般不会改变对象内容;是引用是我们希望避免复制形参。
返回值返回的是ostream类对象的引用,为了与其他输出运算符保持一致,operator<<一般要返回它的ostream形参。同时为了进行连续的运算,如cout<<a<<b; 先打印类对象a,返回对象引用后继续打印b。

C++ 重载运算符和重载函数相关推荐

  1. C++——重载运算符和重载函数

    重载运算符和重载函数 C++ 中的函数重载 C++ 中的运算符重载 C++ 一元运算符重载 C++ 二元运算符重载 C++ 关系运算符重载 C++ 输入/输出运算符重载 C++ 赋值运算符重载 C++ ...

  2. 面向对象编程(三):重载运算符和重载函数

    C++ 重载运算符和重载函数 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是 ...

  3. C++基础教程之重载运算符和重载函数

    C++ 重载运算符和重载函数 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是 ...

  4. C++ | C++ 重载运算符和重载函数

    文章目录 C++ | C++ 重载运算符和重载函数 C++ 重载运算符和重载函数 C++ 中的函数重载 实例1: C++ 中的运算符重载 实例2: 可重载运算符/不可重载运算符 运算符重载实例 运算符 ...

  5. C++ 重载运算符和重载函数(一)

    C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不 ...

  6. 重载运算符作为成员函数还是非成员函数

    一.定义为成员函数的运算符 1. 赋值.调用.下标.成员访问箭头运算符(=.().[].->) 2. 改变对象状态的运算符或者与给定类型密切相关的运算符(递增++.递减--.解引用*) 3. 复 ...

  7. C++语言之可重载运算符/不可重载运算符

    下面是可重载的运算符列表: 双目算术运算符 + (加),-(减),*(乘),/(除),% (取模) 关系运算符 ==(等于),!= (不等于),< (小于),> (大于),<=(小于 ...

  8. 类的6个默认成员函数:构造函数、析构函数、拷贝构造函数、重载运算符、三/五法则

    文章目录 6个默认成员函数 构造函数 概念 默认构造函数的类型 默认实参 概念 默认实参的使用 默认实参声明 全局变量作为默认实参 某些类不能依赖于编译器合成的默认构造函数 第一个原因 第二个原因 第 ...

  9. C++ 重载函数和重载运算符

    C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不 ...

最新文章

  1. pygame里面物体闪烁运动_教师资格【试讲示范】高中物理试讲答辩——《自由落体运动》试讲稿答辩...
  2. 谷歌发布颠覆性研究:不训练不调参,AI自动构建超强网络,告别炼丹一大步...
  3. 自带浏览器_三星手机自带浏览器下载量突破 10 亿次
  4. 解决使用requests_html模块,req.html.render()下载chromium速度慢问题
  5. 【算法】集成学习原理
  6. 监听程序当前无法识别连接符中请求的服务_[Servlet] 18 监听器
  7. MySQL事务及隔离级别详解
  8. 解决VScode无法输出中文的问题
  9. InDesign 软件教程,如何在 InDesign 中缩放和平移文档?
  10. mangodb和php比较,php-mongodb从不同的数据库中选择
  11. 计算机一级考试广告,2013年计算机一级考试MsOffice备考题及答案(21)
  12. android程序表白,打造一款浪漫的Android表白程序
  13. JS、H5调用手机相册摄像头以及文件夹
  14. ACE反应器框架简介
  15. 12月年末总结与新年期望
  16. [附源码]Python计算机毕业设计SSM基于java学科竞赛管理系统(程序+LW)
  17. bimodal or multimodal data test and analysis in R
  18. git基础(7)--打标签
  19. Android使用Bmob移动后端云Restful API需要注意的问题
  20. 生物素化学试剂Dde Biotin-PEG4-azide,生物素-PEG4-叠氮化物 水溶性怎么样了?

热门文章

  1. Java开发常用网址,推荐一些能帮助我们提升开发效率和学识巩固的网址,值得收藏
  2. (matlab实现)sigmoid函数和tanh函数以及ReLU函数
  3. python ndarray合并_python中多维数组ndarray合并
  4. iOS app 更改名字
  5. 音视频编解码 -- 编码参数 CRF
  6. 制作网页常见图片格式及特性介绍
  7. 共读ulord项目分析(二)
  8. Java学习之App开发公司手机端设想
  9. python chrome headless_实战Chrome Headless数据抓取(上)
  10. Nginx 二级目录部署Vue2