运算符重载
第04章 运算符重载

class A { int i; public: A(int a=0){ i=a;} void Show(void) {cout<<"i="<<i<<endl;} void AddA(A &a, A &b) // 利用函数进行类之间的运算 { i=a.i+b.i; } A operator +(A &a) // 重载运算符+ { A t; t.i=i+a.i; return t; } }; void main(void) { A a1(10),a2(20),a3; 相当于a3=a1.operator+(a2) a1.Show (); a2.Show (); a3=a1+a2; //重新解释了加法,可以直接进行类的运算 a3.AddA(a1,a2); //调用专门的功能函数 a3.Show (); }
总结:
重新定义运算符,由左操作符
调用右操作符。最后将函数返
回值赋给运算结果的对象。
由对象c1调用
若已有运算载Complex operator+ (Complex &c1, Complex &c2) ,那下面的表达式还 合法吗 c3=c2+12; // 这个表达式合法吗? int i=3+5; //这个表达式合法吗?
C++基础系列——运算符重载

C++基础系列——运算符重载1. 运算符重载简介所谓重载,就是赋予新的含义。
函数重载(Function Overloading)可以让⼀个函数名有多种功能,在不同情况下进⾏不同的操作。
同样运算符重载(Operator Overloading)可以让同⼀个运算符可以有不同的功能。
可以对 int、float、string 等不同类型数据进⾏操作<< 既是位移运算符,⼜可以配合 cout 向控制台输出数据也可以⾃定义运算符重载:class Complex{public:Complex();Complex(double real, double imag);Complex operator+(const Complex &a) const;void display() const;private:double m_real;double m_imag;};// ...// 实现运算符重载Complex Complex::operator+(const Complex &A) const{Complex B;B.m_real = this->m_real + A.m_real;B.m_imag = this -> m_imag + A.m_imag;return B;// return Complex(this->m_real + A.m_real, this->m_imag + A.m_imag);}int main(){Complex c1(4.3, 5.8);Complex c2(2.7, 3.7);Complex c3;c3 = c1 + c2; // 运算符重载c3.display();return 0;}运算结果7 + 9.5i运算符重载其实就是定义⼀个函数,在函数体内实现想要的功能,当⽤到该运算符时,编译器会⾃动调⽤这个函数,它本质上是函数重载。
运算符重载

运算符重载“千里送鹅毛,礼轻情意重”。
在现代社会中,常有人以千里为单位,送贵重的礼物给对方;也有些人以“钱”为单位来回报他人……其实,这两种做法是不合理的。
因为它混淆了两个概念:一是礼物本身,二是礼物所包含的情感。
如果把“千里”换成金钱、或者权势地位呢?还能成立么?答案显然是否定的。
那就是——运算符重载!运算符重载和运算顺序无关吗?当然不是!你可以说这是误导,但是事实上却并非如此。
因为运算符重载后,结果仍旧是原来的数值,只要求出新的运算符即可得到正确的结果。
而且,运算符重载使用起来更加简便快捷,节省时间。
例如:求x=1/2+3/4的值。
若直接写出运算式: x=(1-3/4)/(1/2+3/4)=1/8。
则需要将 x=1/2+3/4分别进行四次乘除运算才能得到最终结果。
假设每次运算均按照运算符优先级排列,第一步: x=1/2+3/4=0,运算符优先级高于等于号(=),故运算符重载后,运算过程变为:x=1/2+3/4=1/8。
第二步: x=1/2+3/4=1/16,运算符优先级低于等于号(=),故运算符重载后,运算过程变为: x=1/2+3/4=1/32。
第三步: x=1/2+3/4=1/64,运算符优先级再度降低,故运算过程变为:x=1/2+3/4=1/128。
第四步: x=1/2+3/4=1/256,运算符优先级继续降低,故运算过程变为: x=1/2+3/4=1/512。
综上所述,运算符重载与运算顺序没有任何联系。
我们都知道,在电脑中,运算符重载是一项十分复杂的工作。
首先,必须根据问题的特点选择适宜的运算符。
其次,应该考虑运算符重载后的运算效率。
同样的问题,采取不同的运算符重载形式,往往会产生截然不同的结果。
例如:求 x=1/2+3/4的值。
若直接写出运算式: x=(1-3/4)/(1/2+3/4)=1/8。
则需要将 x=1/2+3/4分别进行四次乘除运算才能得到最终结果。
假设每次运算均按照运算符优先级排列,第一步: x=1/2+3/4=0,运算符优先级高于等于号(=),故运算符重载后,运算过程变为: x=1/2+3/4=1/8。
c++学习资料第 06 章 运算符重载

第 6 章 运 算 符 重 载
{ return Complex( c.Real, c.Image ); } void Complex::print()const { cout << '(' << Real << " , " << Image << ')' << endl; } void main() { Complex c1( 2.5,3.7 ), c2( 4.2, 6.5 ) ; Complex c ; c = c1 c2 ; // operator(c1,c2) c.print() ; c = 25 + c2 ; // operator+(25,c2) c.print() ; c = c2 + 25 ; // operator+(c2,52) c.print() ; c = c1 ; // operator(c1) c.print() ; } 当一个运算符的操作需要修改类对象状态时,应该以成员函数重载。例如,需要左值操 作数的运算符(如 =,*=,++ 等)应该用成员函数重载。如果以友员函数重载,可以使用 引用参数修改对象。 当运算符的操作数(尤其是第一个操作数)希望有隐式转换,则重载算符时必须用友员 函数或普通函数。 C++中不能用友员函数重载的运算符有 = () [] -> 6.3 几个典型运算符重载 本节讨论在数学类中常用的几个运算符重载的特点和应用。 6.3.1 重载 ++ 与 自增和自减运算符有前置和后置两种形式。每个重载运算符的函数都必须有明确的特 征,使编译器确定要使用的版本。C++规定,前置形式重载为一元运算符函数,后置形式重 载为二元运算符函数。 【例 64】例 62 中使用了成员函数重载++和运算符。本例用友员函数重载++运算符。 设有简单类定义 class Increase { public : Increase() ; … friend Increase operator ++ ( Increase & ) ; friend Increase operator ++ ( Increase & , int ) ; private : unsigned value ; } ; 则前置重载的实现为: Increase operator++ ( Increase & a ) { a.value ++ ;
4第四章 运算符重载

const complex operator - (const complex &c) const; void display(); //输出复数 private: //私有数据成员 1.是为了堵塞a+b=c的漏洞。 double real; //复数实部 2. 3.是为了扩大适应性。 double imag; //复数虚部 };
17
[ ]运算符重载为成员函数
下标运算符[]可以重载: 重载形式为:operator[](int); 当 X x; 隐含调用。 x[y] 可被解释为: 显式调用。 x. operator [ ](y); 只能重载为成员函数,不能使用友元函数。 这个类显然是个‚数组类‛。
18
前置++和后置++重载为成员函数
9
使用
void main(){
complex c1(5,4),c2(2,10),c3; //三个复数类的对象 cout<<"c1="; cout<<"c2="; c1.display(); c2.display();
c3=c1-c2; //使用重载运算符完成复数减法 cout<<"c3=c1-c2="; c3.display(); 程序输出结果为:
这三个运算符是许多 教课书没有提到的。
唯一的一个三目运 算符不能重载。
3
运算符重载的基础
设计运算符重载函数,首先要了解运算符原本的运算语义。重
载函数要忠实遵守该运算符作用于基本数据类型时的语义,
并表现出自身所特有的性质。 例如:+ 、+= 、=、++(前)、++(后) ....
C_运算符重载_各类详细介绍

▪ 说明
运算符重载函数 operator@()可以返回任何类型,甚至可 以是 void类型,但通常返回类型与它所操作的类的类型 相同,这样可使重载运算符用在复杂的表达式中。例如, 在例7-2中,可以将几个复数连续进行加、减、乘、除的 运算。
用友元函数重载单目运算符时,需要一个显式的操作数, 例7-3中,用友元函数重载单目运算符“-”
#include<iostream.h> class nclass{ int a,b; public:
nclass(int x=0,int y=0) { a=x;b=y;} friend nclass operator -(nclass obj); void show(); };
▪ complex operator+(complex com1,complex com2) { return complex(com1.real+com2.real,com1.imag+com2.imag;}
▪ 这种方法是直接将一个无名临时对象创建到主调函数中,那么 运行效率高于前一种。
▪ 单目运算符重载
nclass operator-(nclass obj) { obj.a=-obj.a;
obj.b=-obj.b; return obj;} void nclass::show() { cout<<"a="<<a<<" b"<<b;} ▪ main() ▪{ ▪ nclass ob1(10,20),ob2; ▪ ob1.show(); ▪ ob2=-ob1; ▪ ob2.show(); ▪ return 0; ▪}
第11章运算符重载

❖ 把一个二元运算符重载成成员函数时,该函数只有一个形 式参数,就是右操作数,当前对象是左操作数。
程序设计 - 9
重载实例
《程序设计》 cs.sjtu 2011.9
❖ 为rational类增加“+”和“*”以及比较 的重载函数,用以替换现有的add和 multi函数
❖ 运算符的重载不能改变运算符的运算对象数。因此,重载 函数的形式参数个数(包括成员函数的隐式指针this)与运 算符的运算对象数相同
❖ 运算符重载可以重载成成员函数也可以重载成全局函数实 现。重载成全局函数时,最好把此函数设为友员函数
❖ 如果作为类的成员函数,它的形式参数个数比运算符的运 算对象数少1。这是因为成员函数有一个隐含的参数this。 在C++中,把隐含参数this作为运算符的第一个参数。
程序设计 - 11
函数实现
《程序设计》 cs.sjtu 2011.9
Rational Rational::operator+(const Rational &r1) const { Rational tmp;
tmp.num = num * r1.den + r1.num * den; tmp.den = den * r1.den; tmp.ReductFraction(); return tmp; }
Rational Rational::operator*(const Rational &r1) const
{ Rational tmp;
tmp.num = num * r1.num;
tmp.den = den * r1.den;
tmp.ReductFraction();
第四章 运算符重载

4.3重载运算符的规则
(1)C++只允许已有的部分运算符实施重载。 (2)不能重载的运算符有五个。 (3)重载不改变操作数的个数。 (4)重载不改变运算符的优先级。 (5)运算符重载函数不能带默认值参数。 (6)运算符重载函数必须与自定义类型的对象联 合使用,其参数至少有一个类对象或类对象引用。 (7)C++默认提供 = 和 & 运算符重载。
例4.1 通过成员函数实现复数的加法。 class Complex { private: double real; double imag; public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} Complex complex_add(Complex &c2); void display(); };
int main() {Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; cout<<"c1=";c1.display(); cout<<"c2=";c2.display(); cout<<"c1+c2=";c3.display(); return 0; }
说明: (1)用运算符重载函数取代了例 4.1中的加法成 员函数,从外观上看函数体和函数返回值都是相 同的。 (2)在主函数中的表达式c3=c2+c1 取代了例4.1 中的c3=plex_add(c2) ,编译系统将表达 式c3=c1+c2 解释为 c1.operator + ( c2 ) 对象c1调用的重载函数operator + ,以c2为实参 计算两个复数之和。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Complex c;
c.real=c2.real+real;
c.imag=c2.imag+imag;
return c;
}
void Complex::display()
{
cout <<real <<"," <<imag <<"i" <<endl;
}
int main()
{
Complex c1(3,4),c2(5,-10),c3;
public:
RMB(){yuan=0;j=0;f=0;};
RMB(int r,int i){yuan=r;j=i;f=i;}
RMB operator + (RMB &c2);
RMB operator - (RMB &c2);
void display();
public:
int yuan;
int j;
Complex(double r,double i){real=r;imag=i;}
Complex operator + (Complex &c2);
void display();
private:
double real;
double imag;
};
Complex Complex::operator +(Complex &c2)
return 0;
}
3.列出代码
1、
(1)通过函数:
#include"iostream"
using namespace std;
class Complex
{
public:
Complex(){real=0;imag=0;};
Complex(double r,double i){real=r;imag=i;}
c3=c1+c2;
cout <<"c1=";c1.display();
cout <<"c2=";c2.display();
cout <<"c1+c2=";c3.display();
return 0;
}
2、
#include"iostream"
using namespace std;
class RMB
{
b.j=b.j+10;
b.yuan=c1.yuan-c2.yuan;
}
else
{
b.yuan=c1.yuan-c2.yuan;
}
}
return b;
}
AD AD::cun(RMB &c1,RMB &c2)
{
AD b;
b.yuan=c1.yuan+c2.yuan;
{
size=v.size;
buffer=new int[size];
for(int i=0;i<size;i++)
buffer[i]=v.buffer[i];}
void Vector::Display(){
for(int j=0; j<size; j++)
cout<<buffer[j]<<endl; }
void Set();
~Vector();
protected:
int size;
inቤተ መጻሕፍቲ ባይዱ* buffer;
};
Vector::Vector(int s){
buffer=new int[size=s];
for(int i=0;i<size; i++)
buffer[i]=i*i;
}
Vector::Vector(Vector & v)
3、以下程序实际要输出0~9之间每个数的平方,请用增加拷贝构造函数的方法避免存在的问题。
#include<iostream>
using namespace std;
class Vector{
public:
Vector(int s=100);
Vector(Vector & v);
void Display();
Complex Add(Complex &c2);
void display();
private:
double real;
double imag;
};
Complex Complex::Add(Complex &c2)
{
Complex c;
c.real=c2.real+real;
c.imag=c2.imag+imag;
int f;
};
class AD:public RMB
{
public:
AD qu(RMB &c1,RMB &c2);
AD cun(RMB &C1,RMB &c2);
};
AD AD::qu(RMB &c1,RMB &c2)
{
AD b;
b.f=c1.f-c2.f;
if(b.f<0)
{
c1.j=c1.j-1;
return c;
}
void Complex::display()
{
cout <<real <<"," <<imag <<"i" <<endl;
}
int main()
{
Complex c1(3,4),c2(5,-10),c3;
c3=c1.Add(c2);
cout <<"c1=";c1.display();
void Vector::Set(){
for(int j=0; j<size; j++)
buffer[j]=j+1;
}
Vector::~Vector(){ delete[]buffer;}
int main()
{ Vector a(10);
Vector b(a);
a.Set();
b.Display();
实验二运算符重载
1.实验目的:
1.学习定义和使用重载运算符。
2.熟悉拷贝构造函数。
2.实验任务:
1、对比通过函数来实现复数相加和通过重载运算符实现复数相加的不同之处。
2、定义RMB类,数据成员有yuan、jf,请为该类定义构造函数、并重载“+”、“-”、“<<”、“>>”。
选做:定义账户类,有账号、户名、余额等属性,具有存款、取款等操作,可以把RMB类对象作为成员,进行存取款操作。
cout <<"c2=";c2.display();
cout <<"c1+c2=";c3.display();
return 0;
}
(2)通过运算符重载:
#include"iostream"
using namespace std;
class Complex
{
public:
Complex(){real=0;imag=0;};
b.f=b.f+10;
b.j=c1.j-c2.j;
if(b.j<0)
{
c1.yuan=c1.yuan-1;
b.j=b.j+10;
b.yuan=c1.yuan-c2.yuan;
}
else
{
b.yuan=c1.yuan-c2.yuan;
}
}
else
{
b.j=c1.j-c2.j;
if(b.j<0)
{
c1.yuan=c1.yuan-1;