vc 04 运算符重载
C++的运算符重载
C++的运算符重载收藏C++中预定义的运算符的操作对象只能是基本数据类型。
但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作。
这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类型执行特定的操作。
运算符重载的实质是函数重载,它提供了C++的可扩展性,也是C++最吸引人的特性之一。
运算符重载是通过创建运算符函数实现的,运算符函数定义了重载的运算符将要进行的操作。
运算符函数的定义与其他函数的定义类似,惟一的区别是运算符函数的函数名是由关键字operator和其后要重载的运算符符号构成的。
运算符函数定义的一般格式如下:<返回类型说明符> operator <运算符符号>(<参数表>){<函数体>}运算符重载时要遵循以下规则:(1) 除了类属关系运算符"."、成员指针运算符".*"、作用域运算符"::"、sizeof运算符和三目运算符"?:"以外,C++中的所有运算符都可以重载。
(2) 重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。
(3) 运算符重载实质上是函数重载,因此编译程序对运算符重载的选择,遵循函数重载的选择原则。
(4) 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。
(5) 运算符重载不能改变该运算符用于内部类型对象的含义。
它只能和用户自定义类型的对象一起使用,或者用于用户自定义类型的对象和内部类型的对象混合使用时。
(6) 运算符重载是针对新类型数据的实际需要对原有运算符进行的适当的改造,重载的功能应当与原有功能相类似,避免没有目的地使用重载运算符。
运算符函数重载一般有两种形式:重载为类的成员函数和重载为类的非成员函数。
非成员函数通常是友元。
C++与面向对象程序设计第四章 运算符重载 (PPT4)
有:函数重载;
运算符重; 运算符重载——同一个运算符可以有多种含义或功能。
4.1 运算符重载的语法规则
函数返回值类型 operator 被重载的运算符(函数参数表)
说明:运算符进行重载本质——是编写运算符重载函数; 函数名——必须以operator开始,后跟被重载的运算符;
Байду номын сангаас
注意几点: 1.只能重载C++中已有的运算符。 2.“.”、“.*”、“::”、“?:”和sizeof这5个运算符不允许被 重载。除此之外,都可以被重载。 3.不能改变运算符的操作数个数。比如,对于单目运算符,它只能 有一个操作数。 4.不能改变运算符原有的优先级。 5.不能改变运算符原有的结合性。 6.不能改变运算符对C++内部那些预定义数据类型的操作方式。
C++与面向对象程序设计
第四章:运算符重载
本章教学内容
运算符重载的语法规则 复数类的运算符重载 (+) 字符串类的运算符重载 (+,=,[]) 运算符“<<”的重载 (复数,字符串对象输出 ) 类型转换函数(C++内部数据类型--->类对象)
第四章 运算符重载
“重载”技术是面向对象程序设计的主要特征之一。
//成员函数的实现CComplex.cpp CComplex::CComplex() //默认构造函数 { m_ Re =0.0; m_ Im =0.0; } CComplex::CComplex(double x,double y) //构造函数 { m_ Re=x; m_ Im=y; } CComplex CComplex::operator +(const CComplex c) //两个复数相加 { return CComplex (m_ Re + c.m_ Re, m_ Im+c.m_ Im); } CComplex CComplex::operator +(const double c) //一个复数加一个double数 { return CComplex ( m_ Re +c , m_ Im); }
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运算符重载其实就是定义⼀个函数,在函数体内实现想要的功能,当⽤到该运算符时,编译器会⾃动调⽤这个函数,它本质上是函数重载。
c++第4章运算符重载
20101411班进入课程
1
第4章 运算符重载
20101412班进入课程
2
教学目标:
• 掌握运算符重载的方法和规则 • 掌握常用双目运算符和单目运算符的重载方法 • 掌握转换构造函数和类型转换函数的使用方法。
问题的引入:复数的相加
复数: 形如a+bi的数,a和b都是浮点数。 a是实部,b是虚部。 复数加法 c3=c1+c2; 对象的运算提供了很大的方便。这就需要对运算符 “+”进行重载。
4
4.1 什么是运算符重载 4.1 什么是运算符重载
所谓重载,就是重新赋予新的含义。典型的重载有 •函数重载 •运算符重载。
5
例4.1 在学习重载运算符以前,要实现两个 复数的相加,得使用函数。
•类的构造:该类包含2个成员变量和3个成员函数 1.成员变量为实部和虚部, 2.成员函数有3个,其中2个为构造函数,一个为普 通函数,它实现复数相加。 构造函数之一为默认构造函数(把实部和虚部初始 化为0),构造函数之二为带两个参数的构造函数 (接收用户对实部和虚部的输入。
方法:定义一个重载运算符的函数,在需要执行 被重载的运算符时,系统就自动调用该函数,以实 现相应的运算。 运算符重载实质:是函数的重载。
10
重载运算符的函数一般格式如下:
函数类型 operator 运算符名称 (形参表列)
{ 对运算符的重载处理
}
举例,想将“+”用于Complex类(复数)的加法运算,函数 的原型可以是这样的: Complex operator+ (Complex& c1,Complex& c2);
• 如何实现c3=1+c2? • 解析:以实现以上语句,“+”不能作为成员函数,只能作 为非成员函数。 friend Complex operator+(int &i,Complex &c)
运算符重载实验报告
运算符重载实验报告运算符重载实验报告引言:运算符重载是C++语言中的一项重要特性,它允许用户自定义运算符的行为。
通过运算符重载,可以使得程序更加直观、简洁,并提高代码的可读性和可维护性。
本实验旨在探索运算符重载的用法和效果。
一、实验目的本实验旨在通过实际操作,深入了解运算符重载的机制和使用方法,以及运算符重载对程序设计的影响。
二、实验环境本实验使用C++编程语言,并在Visual Studio开发环境下进行实验。
三、实验过程1. 了解运算符重载的基本概念运算符重载是指通过定义函数,改变运算符的行为。
在C++中,可以通过重载运算符函数来实现运算符的重载。
运算符重载函数的命名规则为"operator 运算符",例如"operator+"表示重载加法运算符。
2. 实现运算符重载的实验示例为了更好地理解运算符重载的使用方法,我们以矩阵的加法为例进行实验。
首先,定义一个Matrix类,并重载"+"运算符。
```cppclass Matrix {private:int** data;int rows;int cols;public:Matrix(int rows, int cols) {this->rows = rows;this->cols = cols;data = new int*[rows];for (int i = 0; i < rows; ++i) {data[i] = new int[cols];}}Matrix operator+(const Matrix& other) {Matrix result(rows, cols);for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j) {result.data[i][j] = data[i][j] + other.data[i][j]; }}return result;}};```在上述代码中,我们定义了一个Matrix类,其中包含矩阵的数据成员data、行数rows和列数cols。
C++第4章 运算符重载
• • • •
一些特殊操作符的重载
4.4.1 重载++与--运算符 4.4.2 重载赋值运算符 4.4.3 重载[ ]和()运算符 4.4.4 重载插入( <<)和提取( >>)运 算符
14
4.4.1 重载++与--运算符
1.重载为类的成员函数 • 增量运算符++和减量运算符--都是一元运算符, 它们只有一个操作数。另外,增量运算符和减 量运算符可以用于前缀或后缀运算形式。
18
4.4.1 重载++与--运算符
2. 重载为类的友元函数 • 一元运算符重载为类的成员函数时,一般不需 要显示说明参数。因为重载为类的成员函数, 总是隐藏了一个参数,该参数是this指针。当 重载为类的友元函数时,由于不存在隐含的 this指针,对一元运算符来说,友元函数必须 有一个参数。
19
4.4.1 重载++与--运算符
CPoint operator++(CPoint &e){ return CPoint (++e. x, ++e. y); } CPoint operator++(CPoint &e,int){ return CPoint (e.x++,e.y++); } void main(){ CPoint p1(10,10),p2; p2=p1++; p1.display(); p2.display(); p2=++p1; p1.display(); p2.display(); }
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; ▪}
C语言运算符的重载详解
C语⾔运算符的重载详解⽬录写⼀个Add函数为什么不⽤加号作为函数名运算符的重载上⾯问题解决总结写⼀个Add函数我们先讨论下⾯代码,并复习前⾯的内容class Complex{private:double Real, Image;public:Complex() :Real(0), Image(0) {}Complex(double r, double i) :Real(r), Image(i) {}~Complex() {}//Complex Add(const Complex* const this,const Complex &c)Complex Add(const Complex& x)const{Complex y;y.Real = Real + x.Real;y.Image = Image + x.Image;return y;//return Complex(this->Real + x.Real, this->Image + x.Image);}void Print(){cout << Real << "+" << Image << "i" << endl;}};int main(){Complex c1(12, 23);Complex c2(4.5, 5.6);Complex c3;c3 = c1.Add(c2);c3.Print();return 0;}直接return可以使⽤⽆名函数直接代替将亡值对象,相⽐可以省⼀次对象的构建我们再分析如果我们使⽤引⽤返回Add函数const Complex& Add(const Complex& x)const{Complex y;y.Real = Real + x.Real;y.Image = Image + x.Image;return y;//return Complex(this->Real + x.Real, this->Image + x.Image);}若我们以引⽤返回,将亡值对象会创建在Add函数的栈帧中,然后返回将亡值地址,函数return结束该空间会被释放、若没有引⽤,构建⽆名对象也就是将亡值对象会构建在主函数的空间中,这⾥使⽤将亡值对象值给到c3是没有问题的我们查看对象的构造与析构class Complex{private:double Real, Image;public:Complex() :Real(0), Image(0) {}Complex(double r, double i) :Real(r), Image(i){cout << "Create:" << this << endl;}Complex(const Complex& x):Real(x.Real),Image(x.Image){cout << "Copy Create:" << this << endl;}~Complex(){cout << "~Complex:" << this << endl;}//Complex Add(const Complex* const this,const Complex &c)Complex Add(const Complex& x)const{return Complex(this->Real + x.Real, this->Image + x.Image);}void Print(){cout << Real << "+" << Image << "i" << endl;}};int main(){Complex c1(12, 23);Complex c2(4.5, 5.6);Complex c3;c3 = c1.Add(c2);c3.Print();return 0;}⾸先我们使⽤引⽤返回需要加上const修饰,这是因为我们返回将亡值在临时空间具有常性,所以普通引⽤是不能进⾏返回的,需要使⽤常引⽤返回const Complex& Add(const Complex& x)const{return Complex(this->Real + x.Real, this->Image + x.Image);}我们发现对临时对象的构建后马上就进⾏析构,那么是怎么将数据拿出给到c3的?这个在最后我们进⾏分析为什么不⽤加号作为函数名//Complex operator+(const Complex* const this,const Complex &c)Complex operator+(const Complex &c) const{return Complex(this->Real + x.Real, this->Image + x.Image);}这⾥是不可以的,加号是⼀个操作符,不能使⽤操作放作为有效的函数名称;但是在C++中为了使这些操作符号能够当作函数名,那么我们需要在前⾯加上⼀个关键字operator//Complex operator+(const Complex* const this,const Complex &c)Complex operator+(const Complex &c) const{return Complex(this->Real + x.Real, this->Image + x.Image);}也就是告诉编译器,加号是⼀个有效的函数名,这就叫做运算符的重载;随后我们之间使⽤ c3 = c1 + c2 就是可以的int main(){Complex c1(12, 23);Complex c2(4.5, 5.6);Complex c3;c3 = c1 + c2;//编译器编译会是下⾯的情况//c3 = c1.operator+(c2);//c3 = operator+(&c1,c2); 加上this指针}运算符的重载⼀个对象,编译器会给它有6个缺省函数我们再来看下⾯这个问题//我们写⼀个赋值运算符重载void operator=(const Object& obj){this->value = obj.value;}//返回类型为void,这样不可以就不可以连等//obja = objb = objc;//obja = objb.operator=(objc);//obja = operator=(&objb,objc); 返回的⽆类型,不能给obja赋值且赋值函数不可以定义为const修饰Object& operator=(const Object& obj){this->value = obj.value;return *this;}obja = objb = objc;//改写obja = objb.operator=(objc);obja = operator=(&objb,objc);obja.operator=(operator=(&objb,objc));operator=(&obja,operator=(&objb,objc));通过返回对象,就可以实现连等;并且我们可以通过引⽤返回,因为此对象的⽣存期并不受函数的影响,不会产⽣⼀个临时对象作为⼀个过度防⽌⾃赋值若是我们将obja给obja赋值,也就是⾃赋值obja = objaoperator=(&obja,obja);我们就需要进⾏⼀步判断Object& operator=(const Object& obj){if(this != &obj)//防⽌⾃赋值{this->value = obj.value;}return *this;}上⾯问题解决我们通过这段代码来看,与上⾯问题相同Object& operator=(const Object& obj){if (this != &obj){this->value = obj.value;}return *this;}};Object& fun(const Object& obj){int val = obj.Value() + 10;Object obja(val);return obja;}int main(){Object objx(0);Object objy(0);objy = fun(objx);cout << objy.Value() << endl;return 0;}我们在这⾥希望通过引⽤返回,这⾥return的临时对象会构建在fun函数的栈帧中,并且在函数结束栈帧释放,随后调⽤赋值运算符重载,但是数值依旧是正确的我们跟踪这个被析构对象的地址,⾸先我们定位在fun函数的return obja;,随后进⼊析构函数将我们的obja进⾏析构接着运⾏到回到主函数进⾏赋值,接着进⼊赋值运算符重载,可以看到,这⾥的obj地址与已被析构的obja地址相同可以看到这个值依旧存在,依旧可以打印给出,这是因为vs2019的特殊性质造成的;我们每次运⾏程序会发现每次的对象地址都在变化,逻辑地址会随机改变,被析构对象的栈帧不会被接下来的赋值运算符重载扰乱地址空间,所以即使我们引⽤返回的对象已经死亡依旧可以将数值正确返回但是在vc中,我们得到的值会是随机值,这是因为vc中每次运⾏程序地址都不会改变,当我们从fun函数退出进⼊赋值语句中,就会将原本存储数据的地址扰乱,继⽽变成了随机值尽管我们引⽤返回能够将数据正确打印,但是该对象已经死亡,这是不安全的,所以我们⼀定不要以引⽤返回对象VS2019具有⼀个特点:当我们调⽤函数,若函数中没有定义局部变量或局部对象时,该函数基本不对栈帧进⾏清扫总结到此这篇关于C语⾔运算符的重载详解的⽂章就介绍到这了,更多相关C语⾔运算符重载内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
C++运算符重载三种形式(成员函数,友元函数,普通函数)详解
C++运算符重载三种形式(成员函数,友元函数,普通函数)详解三种重载⽅式⾸先,介绍三种重载⽅式:1//作为成员函数重载(常见)2class Person{3 Private:4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}8bool operator<(const Person& b);910 };11bool Person::operator<(const Person& b)12 {13//作为成员函数时,*this即为左操作数a14 ...15 }1//作为友元函数重载2class Person{3private:4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}8 friend bool operator<(const Person& a,const Person& b);910 };11bool operator<(const Person& a,const Person& b)12 {13 ...14 }1//作为普通函数重载(不推荐)2class Person{3public://注意,重载运算符为普通函数时,使⽤到的类成员必须为public4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}89 };10bool operator<(const Person& a,const Person& b)11 {12 ...13 }作为成员函数重载先介绍第⼀种:bool Person::operator<(const Person& b),bool是函数返回类型,Person::只是指定了成员函数所属类名。
VC++第六章运算符重载
6.1 运算符重载的语法6.2 一元运算符6.3 二元运算符的重载6.4 特殊的运算符6.4.1 =运算符的重载6.4.2 ++和--运算符的重载6.4.3 new 和delete 运算符的重载6.4.4 []的重载第6 章运算符重载运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据导致不同类型的行为。
它的主要优点之一就是用户自定义的数据类型可使用编译系统预定义的运算符。
【6.1 运算符重载的语法】定义一个重载的运算符是这个函数的名字必须以operator开头。
运算符重载函数的一般形式为:类型类名::operator 重载的运算符(参数列表){相关操作;}它的参数个数由以下两个因素决定:(1) 该操作符是一元操作符还是二元操作符当运算符函数是全局函数时,需要在类中将该函数说明为友员。
复数类运算符重载//EXAMPLE6_01.H#ifndef EXAMPLE6_01_H //用于防止文件的多重编译#define EXAMPLE6_01_H #include<iostream.h>class zComplex {double realpart;double imagpart;(2) 它是被定义为全局函数还是一个成员函数。
如果是全局函数,那么对于一元操作符它的参数个数就是1个(后置++、--除外),二元操作符的参数个数是2个;如果是成员函数,那么对于一元操作符的参数个数为0,二元操作符的参数个数为1。
这是由于该类本身也作为一个操作数参与计算,所以成员函数的参数要比全局函数的参数个数少1。
例6-1(续)public:// 构造函数zComplex();zComplex(double r1,double i1);zComplex(const zComplex& c);zComplex(double c){realpart = (double)c;imagpart = 0;}// 取复数的实部和虚部double real();double imag();friend double real(const zComplex&);friend double imag(const zComplex&);//运算符重载为成员函数zComplex operator+(const zComplex&);zComplex operator-(const zComplex&);zComplex operator*(const zComplex&);zComplex operator/(const zComplex&);zComplex operator=(const zComplex&);//运算符重载为友元函数friend int operator ==(const zComplex&,const zComplex&);friend int operator !=(const zComplex&,const zComplex&);// show complex void print();};#endif(1)虽然运算符重载可以改变运算符原来的行为,但是它并不能改变运算符的优先级、结合性、操作数的个数。
4 运算符重载
可以将+代表的操作看成一个函数:+为函数的名字,+操作的两个操 作数的类型即为函数形参的类型,+操作的结果的类型即为函数的返回 值类型。
北京化工大学 VC++ 教学课件
2
计算机系 江志英 jiangzy@
运算符重载的提出
C/C++中,每种基本数据类型的变量都可通过几种运算符来做相关计 算,如int型变量,它们可以同“+”,“-”,“*”,“/”等运算符 来做加法,减法,乘法,除法等。如:
4 5 6
常用运算符的重载
重载赋值运算符operator=
重载输入/输出运算符 << | >>
重载下标运算符operator[ ]
重载类型转换函数
北京化工大学 VC++ 教学课件
4
计算机系 江志英 jiangzy@
运算符重载的基本语法
运算符的使用和普通函数在语法上有所不同,但是可以将 运算符看作是一种特殊的函数,操作数是函数的参数,运 算结果是函数的返回值。
北京化工大学 VC++ 教学课件
14
计算机系 江志英 jiangzy@
// 重载运算符的使用示例 int main() { Byte a, b, *bp; +b; -b; ~b; bp = &b; !b; ++b; b++; --b; b--; } //end of main()
3
Vector vec1,vec2 vec1+vec2; vec1-vec2; vec1*vec2; vec1/vec2; 两个向量类对象的加减乘除
C++提供了运算符重载机制来帮助我们实现上述目的。
运算符重载——精选推荐
运算符重载运算符重载学习运算符重载,让运算符能做⼀些原来做不了的事情,⽅便它的使⽤⼀、运算符重载的概念1、什么是运算符重载1.重载:重新载⼊,就像之前学的函数重载,对⼀个已有的函数赋值⼀个新的定义,因此同⼀个函数名就可以有不同的含义。
2.运算符也是可以重载的,⽐如cout在输出⼀个变量的时候,能接受不同类型的数据并输出,他就是重载了<<运算符,这个就是运算符重载3.所以运算符重载指的是对已有的运算符重新定义新的运算规则,以适应不同的数据类型,当然重载之后之前的运算规则还是有的2、为什么要进⾏运算符重载1.运算符重载之后可以让运算符去适应不同的数据类型,对于基本数据类型,系统给出了运算符的操作规则,对于⾃定义数据类型来说,系统不知道该给出什么规则class student{int id;int age;char name[20];public:student(int id,int age,const char* name){this->id=id;this->age=age;strcpy(this->name,name);}}student stu1(1,23,"张三");student stu2(2,24,"李四");stu1+stu2;//如果是这样相加,那么应该加的是什么呢?编译器是不知道的,所以编译器就提供了运算符重载这个机制,让⽤户⾃定义运算符的运算规则⼆、运算符重载1、运算符重载类中定义1.关键字:operator,通过关键字来定义运算符重载(跟写个函数⼀样)2.定义:函数返回值类型 operator 要加载的运算符(参数列表){函数体;}这⾥把运算符的使⽤,理解为调⽤函数,只是和平时的调⽤函数有⼀点区别#include<iostream>#include<string>using namespace std;class student{int id;int age;string name;public:student(int age){this->age = age;id = 1;name = "sss ";}student(int id, int age, string name){this->id = id;this->age = age;this->name = name;}void showstudent(){cout << id << "\t" << age << "\t" << name << endl;}student operator+(student& p1)//这个函数会返回⼀个新的对象{int x=this->age + p1.age;student p(x);return p;//返回的是⼀个对象,会调⽤拷贝构造}int operator-(int x){return this->id - x;}void operator+(student&p2){cout << this->id + p2.id << endl;}};//1.操作这个运算符之后,返回值类型是什么int main(){student p1(0, 1, "yunfei");int x = p1.operator-(1);cout << x << endl;student stu1(1, 23, "张三");student stu2(2, 24, "李四");//student stu3 = stu1.operator+(stu2);//student stu3 = stu1 + stu2;stu1 + stu2;//stu3.showstudent();system("pause");return 0;}注意:因为我们这个运算符是在类中写的,所以是通过对象调⽤的,那么this指针会占⼀个参数,⽽且是第⼀个参数,也就是说我们重载⼀个运算符,是在类中,⽽这个运算符是个单⽬运算符,那么参数列表就不⽤写东西了,是双⽬运算符,那么就需要传另⼀个参数进来绝⼤部分的运算符重载都可以参照上⾯这个+号重载2、运算符重载的特点1.⼏乎所有的运算符都可以被重载,除了 . :: ()?() ) sizeof()2.运算符重载基本出现在类中和结构体中3.运算符可以理解为函数的⼀个表现3、运算符重载的注意事项1.重载运算符,这个重载的运算符还是满⾜原来的原则,但不能说重载+号,结果做的事-号的事,这样会使运算符的运⽤上增加很⼤的难度2.运算符重载的参数,类中重载调⽤对象会占⼀个参数,就是this会占⼀个参数,参数列表就是⽤来表⽰运算符的操作的3.对于运算符重载的调⽤,可以直接使⽤运算符,也可以通过对象 . 出来调⽤4.考虑返回值,不同的运算符有不同的返回值,要记得满⾜运算符原来的规则4、使⽤友元函数,实现运算符重载1.类在已经实现且部分修改的情况下下,需要进⾏运算符重载,就可以通过友元的⽅式来进⾏重载#include<iostream>#include<string>using namespace std;class person{int id;int age;string name;public:person(int id, int age, string name){this->id = id;this->age = age;this->name = name;}void showperson(){cout << id << "\t" << age << "\t" << name << endl;}friend int operator+(person&p1, person&p2);};//形参使⽤的是类对象的引⽤,在实参传对象的时候不会调⽤拷贝构造int operator+(person&p1, person&p2){return p1.id + p2.id;}//1.操作这个运算符之后,返回值类型是什么int main(){person stu1(1, 23, "张三");person stu2(2, 24, "李四");int x = operator+(stu1, stu2);//显⽰调⽤int y = stu1 + stu2;//隐式调⽤cout << x << endl << y << endl;system("pause");return 0;}容器:#include<iostream>#include<vector>using namespace std;int main(){//int 是v1这个容器存的类型vector<int> v1;for (int i = 0; i < 10; i++){//push_back()是⼀个函数,功能是尾插元素v1.push_back(i + 1);}for (int i = 0; i < 10; i++){cout << v1[i] << "\t";}system("pause");return 0;}左移右移运算符重载:#include<iostream>using namespace std;class person{int id;public:person(int id){this->id = id;}friend ostream& operator<<(ostream& os, person& p1);friend istream & operator>>(istream & in, person & p2);};//左移右移运算符重载,必须在类外重载,通过友元实现ostream& operator<<(ostream& os, person& p1)//左移运算符{os << p1.id << endl;return os;//返回的是⼀个cout,⽽且只能⽤引⽤}istream & operator>>(istream & in, person & p2)//右移运算符{in >> p2.id;return in;}int main(){person p1(10), p2(20);cin >> p1 >> p2;cout << p1 << endl << p2 << endl;system("pause");return 0;}前++,后++运算符重载:#include<iostream>using namespace std;class person{int id;public:person(int id){this->id = id;}person& operator++()//前++{this->id++;return *this;}person& operator++(int)//后++,int是⼀个占位符,⽤来区分前++和后++的{static person temp = *this;//引⽤不能返回局部变量,要⽤静态变量this->id++;return temp;}friend ostream& operator<<(ostream& os, person& p1);friend istream & operator>>(istream & in, person & p2);};//左移右移运算符重载,必须在类外重载,通过友元实现ostream& operator<<(ostream& os, person& p1)//左移运算符{os << p1.id << endl;return os;//返回的是⼀个cout,⽽且只能⽤引⽤}istream & operator>>(istream & in, person & p2)//右移运算符{in >> p2.id;return in;}int main(){person p1(10), p2(20);//cin >> p1 >> p2;//cout << p1 << endl << p2 << endl;cout << p1 ;//10cout << p1++ ;//10cout << p1 ;//11cout << ++p1 ;//12cout << p1 ;//12system("pause");return 0;}等号运算符重载:#include<iostream>using namespace std;class person{char* name;public:person(const char* name){this->name = new char[strlen(name) + 1];strcpy(this->name, name);}person& operator=(person&p1)//⽤不⽤引⽤传参,要看返回的对象会不会消失 {if (this->name != NULL){delete[]this->name;this->name = NULL;}this->name = new char[strlen() + 1];strcpy(this->name, );return *this;}void show(){cout << name << endl;}~person()//如果有申请函数,就要加上析构函数{if (name != NULL){delete[]name;name = NULL;}}};int main(){{person p1("张三"), p2("李四"), p3("王五");p1 = p2 = p3;p1.show();p2.show();p3.show();}//加上⼤括号,让对象死亡,就能调⽤析构函数system("pause");return 0;}智能指针和==号运算符重载:#include<iostream>using namespace std;class person{int id;public:person(int id){this->id = id;}void show(){cout << id << endl;}bool operator==(person& p){return this->id == p.id;}~person(){cout << "person的析构函数" << endl;}};class smartpointer{person* ps;//包含你要new出来的对象的类的指针public:smartpointer(person* p){ps = p;}//重载->person* operator->()//传回来的是地址,不是对象,不⽤引⽤{return ps;}//重载*person& operator*()//返回的是对象,会调⽤拷贝构造,所以⽤返回值⽤引⽤,就不会再调⽤拷贝构造了 {return *ps;//得到⼀个对象,}~smartpointer(){if (ps != NULL){delete ps;ps = NULL;}}};int main(){{smartpointer p(new person(5));p->show();(*p).show();person p1(1), p2(3);cout << (p1 == p2) << endl;}//有三个对象,所以析构函数执⾏了三次system("pause");return 0;}[]运算符重载:#include<iostream>using namespace std;class person{char* name;public:person(const char* name){this->name = new char[strlen(name) + 1];strcpy(this->name, name);}char& operator[](int index){return name[index];}~person(){if (name != NULL){delete[]name;name = NULL;}cout << "这是析构函数" << endl;}};int main(){person p("asdfg");cout << p[3] << endl;system("pause");return 0;}c++引⽤作为函数返回值:1.以引⽤返回函数值,定义函数时需要在函数名前加 &2.⽤引⽤返回⼀个函数值的最⼤好处是,在内存中不产⽣被返回值的副本3.返回值为引⽤的时候,返回的是⼀个地址,隐形指针4.当返回值不是引⽤时,编译器会专门给返回值分配出⼀块内存的引⽤作为返回值,必须遵守以下规则:(1)不能返回局部变量的引⽤。
C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数
C++学习之路—运算符重载(⼆)运算符重载作为类的成员函数和友元函数对运算符重载的函数有两种处理⽅式:(1)把运算符重载的函数作为类的成员函数;(2)运算符重载的函数不是类的成员函数,在类中把它声明为友元函数。
1 把运算符重载函数作为类的成员函数例1:为了便于说明问题,将重载函数的定义重写如下:1: Complex Complex :: operator + ( Complex& c2 )2: {3: Complex c ;4: c.real = real + c2.real ;5: c.imag = imag + c2.imag ;6:return c ;7: }有⼈可能会提出这样的疑问:“+”是双⽬运算符,为什么重载函数只有⼀个参数呢?实际上,运算符重载函数应当有两个参数,但是,由于重载函数是Complex类中的成员函数,因此有⼀个参数是隐含的,运算符函数是⽤this指针隐式的访问类对象的成员。
可以看到operator+访问了两个对象中的成员,⼀个是this指针指向的对象中的成员,⼀个是形参对象中的成员。
2 把运算符重载函数作为类的友元函数运算符重载函数除了可以作为类的成员函数外,还可以是⾮成员函数。
在有关的类中把它声明为友元函数,即友元运算符重载函数。
例2:将运算符+重载为适⽤于复数加法,重载函数不作为成员函数,⽽放在类外,作为Complex类的友元函数。
1:class Complex2: {3:public:4: ...5:friend Complex operator + ( Complex& c1 , Complex& c2 ) ; //重载函数作为友元函数6:private:7:double real ;8:double imag ;9: };10:11: Complex operator + ( Complex& c1 , Complex& c2 ) //定义运算符+重载函数12: {13: Complex c ;14: c.real = c1.real + c2.real ;15: c.imag = c1.imag + c2.imag ;16:return c ;17: }这个程序和把运算符重载函数作为类的成员函数相⽐,只做了⼀处改动,就是将运算符重载函数作为类外的普通函数,并在Complex类中声明它为友元函数。
C++运算符重载知识点总结
C++运算符重载知识点总结C++运算符重载知识总结5.1编译时的多态性与运⾏时的多态性在C++中,多态性的实现和联编(也叫绑定)这⼀概念有关。
源程序—>编译、连接—>可执⾏⽂件这⼀过程时把可执⾏代码联编在⼀起的过程。
其中在运⾏之前就完成的联编叫做静态联编,⼜叫前期联编;⽽在程序运⾏时才完成的联编叫动态联编,也叫后期联编。
静态联编(前期联编):指系统在编译时就决定如何实现某⼀动作。
要求在编译时就知道调⽤函数的全部信息。
静态联编⽀持的多态性成为编译时多态性(静态多态性),通过函数重载(包括运算符重载)和模板实现。
优点:函数调⽤速度很快,效率⾼。
动态联编(后期联编):指系统在运⾏时动态实现某⼀动作。
采⽤这种联编⽅式,⼀直要到程序运⾏时才能确定调⽤哪个函数。
动态联编⽀持的多态性成为运⾏时多态性(动态多态性),通过虚函数实现。
优点:提供了更好的灵活性、问题抽象性和程序易维护性。
5.2运算符重载5.2.1在类外定义的运算符重载函数为了表达上的⽅便,⼈们希望预定义的运算符(如+、-、*、/等)在特定的对象上以新的含义进⾏解释,如希望能够实现两个复数类的加减,这就需要通过运算符重载来解决。
C++中进⾏运算符重载时,必须定义⼀个运算符重载函数,其名字为operator,后随⼀个要重载的运算符。
#includeusing namespace std;class Complex{public:double real;double imag;Complex(double r=0,double i=0){real=r;imag=i;}};Complex operator+(Complex co1,Complex co2)//类外定义运算符+的重载函数{Complex temp;temp.real=co1.real+co2.real;temp.imag=co1.imag+co2.imag;return temp;}int main(){Complex com1(1.1,2.2),com2(3.3,4.4),total1,total2;total1=operator+(com1,com2);//运算符重载函数第⼀种调⽤⽅式,显式调⽤cout<<"real1="<total2=com1+com2;//运算符重载函数第⼆种调⽤⽅式,隐式调⽤cout<<"real2="<return0;}C++语⾔对运算符重载制定了以下⼀些规则:1.绝⼤部分运算符可以重载,不能重载的只有以下⼏个:2.3.运算符重载是针对新类型数据的实际需要,不建议改变原运算符的含义。
c++面向对象程序设计 第四章 运算符重载
授课人:髙悟实
01 第一章 C++的初步知识 02 第二章 类和对象
目录
03 第三章 关于类和对象的进一步讨论 04 第四章 运算符重载 05 第五章 继承与派生 06 第六章 多态性与虚函数 07 第七章 输入输出流
CONTENTS
第四章
C++的初步知识
4.1
什么是运算符重载 运算符重载的方法 重载运算符的规则 运算符重载函数作为类成员函数和友 元函数 重载双目运算符 重载单目运算符 重载流插入运算符和流提取运算符
规则和限制
•
C++中可以重载除下列运算符外的所有运算符:
. .* :: ?:
• • •
只能重载C++语言中已有的运算符,不可臆造新的。 不改变原运算符的优先级和结合性。 不能改变操作数个数。
•
经重载的运算符,其操作数中至少应该有一个是自定义类型。
4.2运算符重载的方法
两种形式
• •
重载为类成员函数。 重载为友元函数。
4.1什么是运算符重载
运算符重载的实质 • • • 运算符重载是对已有的运算符赋予多重含义。 必要性 C++中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自 定义类型(如类) • • 实现机制 将指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函 数的实参。 • 编译系统对重载运算符的选择,遵循函数重载的选择原则。
double imag;
public: Complex(){real=0;imag=0;} Complex(double r,double
i){real=r;imag=i;}
C++学习之运算符重载的总结
C++学习之运算符重载的总结C++学习之运算符重载的总结运算符重载是对已有的运算符赋予多重含义,使同⼀个运算符作⽤域不同类型的数据导致不同⾏为的发⽣,C++为运算符重载提供了⼀种⽅法,即运算符重载函数。
其函数名字规定为operator后紧跟重载运算符。
⽐如:operator+(),operator*()等。
(1)运算符重载函数作为类的友元函数的形式: class 类名 { friend 返回类型 operator运算符(形参表); } 类外定义格式: 返回类型 operator运算符(参数表) { 函数体 }友元函数重载双⽬运算符(有两个操作数,通常在运算符的左右两则),参数表中的个数为两个。
若是重载单⽬运算符(只有⼀个操作数),则参数表中只有⼀参数。
同⼀个运算符可以定义多个运算符重载函数来进⾏不同的操作。
(2)运算符重载函数作为类的成员函数的形式: class 类名 { 返回类型 operator 运算符(形参表); } 类外定义格式: 返回类型类名:: operator 运算符(形参表) { 函数体; }对于成员函数重载运算符⽽⾔,双⽬运算符的参数表中仅有⼀个参数,⽽单⽬则⽆参数。
同样的是重载,为什么和友元函数在参数的个数上会有所区别的。
原因在于友元函数,没有this指针。
对于双⽬运算符⽽⾔,运算符重载函数的形参中仅为⼀个参数,它作为运算符的右操作数(如com2对象),⽽当前对象作为左操作数(如:上述中的com1对象),它是通过this指针隐含传递给成员运算符重载函数的。
例如下⾯这样的定义:Complex operator+(Complex com1);//成员函数重载双⽬运算符+20Complex Complex::operator+(Complexcom1)21{22return Complex(real+com1.real,imag+com1.imag);23}对于单⽬运算符⽽⾔,当前对象作为运算符的操作数。
C程序设计运算符重载资料
•
{
目的对象与源对象不是同一个对象
•
……
复制被被赋值对象
•
}
•
*;
返回目的对象
•}
*重载赋值运算符“=”
• 如用户没有为一个类重载赋值运算符,编译程序将生成一个默认赋值运算符函数。赋值运算 把源对象的数据成员逐个地复制到目的对象的相应数据成员
0;
返回值0, 返回操作系统
}
程序运行时屏幕输出如下: 6 -6 请按任意键继续. . .
用类的友元函数重载双目运算符
• 将双目运算符重载为类的友元函数时,友元函数形参表中包含有两个参数,这两个参数分别 作为运算符的左、右操作数。
例4.6 双目运算符重载为类的友元函数示例。
<>
编译预处理命令
;
使用命名空间
例4.8 双目运算符重载为普通函数示例。 声明整型类
{
:
数据成员
;
数据值
:
公有函数
( n = 0): (n){ }
构造函数
( n) { = n; }
设置数据值
() { ; } 返回数据值
};
( , ) 重载运算符"+"
{ (() + ()); }
()
主函数()
{
i(6), j(9), k;
定义整型对象
例4.5 单目运算符重载为类的友元函数示例。
<>
编译预处理命令
;
使用命名空间
声明整型类
{
: 数据成员
在 6.0下会出现的编译时错语,是 6.0的一个,在
<> ;;
编译预处理:
:
改为:
运算符重载详解
运算符重载详解1.运算符重载定义:C++中预定义的运算符的操作对象只能是基本数据类型。
但实际上,对于许多⽤户⾃定义类型(例如类),也需要类似的运算操作。
这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够⽤于特定类型执⾏特定的操作。
运算符重载的实质是函数重载,它提供了C++的可扩展性,也是C++最吸引⼈的特性之⼀。
运算符重载是通过创建运算符函数实现的,运算符函数定义了重载的运算符将要进⾏的操作。
运算符函数的定义与其他函数的定义类似,惟⼀的区别是运算符函数的函数名是由关键字operator和其后要重载的运算符符号构成的。
运算符函数定义的⼀般格式如下:<返回类型说明符> operator <运算符符号>(<参数表>){<函数体>} 2.运算符重载时要遵循以下规则:(1) 除了类属关系运算符"."、成员指针运算符".*"、作⽤域运算符"::"、sizeof运算符和三⽬运算符"?:"以外,C++中的所有运算符都可以重载。
(2) 重载运算符限制在C++语⾔中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。
(3) 运算符重载实质上是函数重载,因此编译程序对运算符重载的选择,遵循函数重载的选择原则。
(4) 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。
(5) 运算符重载不能改变该运算符⽤于内部类型对象的含义。
它只能和⽤户⾃定义类型的对象⼀起使⽤,或者⽤于⽤户⾃定义类型的对象和内部类型的对象混合使⽤时。
(6) 运算符重载是针对新类型数据的实际需要对原有运算符进⾏的适当的改造,重载的功能应当与原有功能相类似,避免没有⽬的地使⽤重载运算符。
(7)重载运算符的函数不能有默认的参数,否则就改变了运算符的参数个数,与前⾯第3点相⽭盾了;(8)重载的运算符只能是⽤户⾃定义类型,否则就不是重载⽽是改变了现有的C++标准数据类型的运算符的规则了,会引会天下⼤乱的;(9)⽤户⾃定义类的运算符⼀般都必须重载后⽅可使⽤,但两个例外,运算符“=”和“&”不必⽤户重载;(10)运算符重载可以通过成员函数的形式,也可是通过友元函数,⾮成员⾮友元的普通函数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
于是: 于是:
string x,y; x=x+y; //表示串 和串 合并,放入串 表示串x 表示串 和串y 合并,放入串x
这就使对基本类型的预定义运算符" 的含义在串类中被扩展 这就使对基本类型的预定义运算符"+"的含义在串类中被扩展 为对串类对象的合并操作,即运算符"+"被重载. 为对串类对象的合并操作,即运算符" 被重载. 被重载 运算符重载应注意的几个问题: 运算符重载应注意的几个问题: 1,哪些运算符可以重载? 哪些运算符可以重载? 中除了下面四种运算符外, 在C++ 中除了下面四种运算符外,系统预定义的运算符都 能被重载. 能被重载.
string x,y;
那么, 实现两个串的合并. 那么,可以使用函数strcat(x,y)实现两个串的合并. 如果在表示字符串的类对象x, 的特定环境下,运算符" 使 如果在表示字符串的类对象 ,y 的特定环境下,运算符"+"使 用于类对象,能被解释为串对象x 的合并, 用于类对象,能被解释为串对象 和y 的合并,则编程就更方便 了.
例如:下边是运算符重载的另一个例子,程序实现了复数的加 例如:下边是运算符重载的另一个例子, 和减运算. 和减运算.
#include <iostream.h> class Complex { public: Complex() { real=imag=0.0; } Complex(double r) { real=r; imag=0.0; } Complex(double r,double i) { real=r; imag=i; } Complex operator+(const Complex& c); Complex operator-(const Complex& c); friend void print(const Complex& c); private: double real,imag; };
::(Scope resolution); . (Member selection); ->(Member selection through pointer to member); ?:(Conditional expression).
2,运算符重载要保持原运算符的下述特性不变: 运算符重载要保持原运算符的下述特性不变: 优先级和结合性不变; 优先级和结合性不变; 操作数个数不变; 操作数个数不变; 语法结构不变. 语法结构不变. 3,运算符重载实际上是通过定义一个函数来实现的.运算符重 运算符重载实际上是通过定义一个函数来实现的. 载归根结底是函数的重载.编译器选择重载的运算符是遵循函 载归根结底是函数的重载. 数重载的选择原则, 数重载的选择原则,即按不同类型或个数的参数来选择不同的 重载运算符. 重载运算符. 4,运算符重载应符合使用习惯,便于理解.如果在字符串类中 运算符重载应符合使用习惯,便于理解. 把"*"运算符重载为两个对象的合并操作,就不如把"+"运 "运算符重载为两个对象的合并操作,就不如把" 运 算符重载,更易于理解. 算符重载,更易于理解. 5,运算符重载不能创造新的运算符号.例如,不能创造一个新 运算符重载不能创造新的运算符号.例如, 运算符号" " 表示幂运算. 运算符号"**",表示幂运算.
friend type operator@(参数表 参数表) 参数表 {
相对于该类而定义的操作(运算符重载函数体 相对于该类而定义的操作 运算符重载函数体) 运算符重载函数体
}
单目运算符重载,参数表中只有一个形参数; 单目运算符重载,参数表中只有一个形参数; 双目运算符重载,参数表中有两个形参数. 双目运算符重载,参数表中有两个形参数. 运算符重载为成员函数和友元函数形式的主要区别在于前者 指针,后者无this 指针. 指针. 有this 指针,后者无
结果: 结果:
mycounter=1; mycounter=2; …… mycounter=12; mycounter=10;
注意:程序中重载运算符"++","--"和"( )"使用的操作数为 注意:程序中重载运算符" , 和 使用的操作数为 类对象;预定义运算符" 使用的操作符为基本类型. 类对象;预定义运算符"++","--"使用的操作符为基本类型. , 使用的操作符为基本类型
它是一种特殊的成员函数,其语法形式为: 它是一种特殊的成员函数,其语法形式为:
type X::operator@(参数表) (参数表 参数表)
{ //相对于该类而定义的操作 运算符重载函数体 相对于该类而定义的操作(运算符重载函数体 相对于该类而定义的操作 运算符重载函数体) }
其中, 为函数的返回类型; 其中,type 为函数的返回类型; @是泛指要重载的运算符号; 是泛指要重载的运算符号; 是泛指要重载的运算符号 X是重载该运算符的类的类名; 是重载该运算符的类的类名; 是重载该运算符的类的类名
§4.2 运算符重载的语法形式
在C++中,运算符重载是通过运算符重载函数实现的,运 中 运算符重载是通过运算符重载函数实现的, 算符重载函数一般采用下述两种形式之一. 算符重载函数一般采用下述两种形式之一. 成员函数的形式; 成员函数的形式; 友元函数的形式. 友元函数的形式.
1,运算符重载的成员函数形式 ,
§4.1 重载运算符
在基本数据类型上,系统提供了许多预定义的运算符. 在基本数据类型上,系统提供了许多预定义的运算符. 例如: 例如:
int x,y; y=x+y;
对基本类型,这些运算符的操作具有特定的含义. 对基本类型,这些运算符的操作具有特定的含义. 如果string 类的两个对象 和y串要合并,以构成一个新字符串, 类的两个对象x 串要合并, 如果 串要合并 以构成一个新字符串, 即:
例如:下面程序定义了一个类名为 的计算器, 例如:下面程序定义了一个类名为Counter 的计算器,初始化 三个运算符, 为0,为计算器重载了"++","--","( )"三个运算符,分别 ,为计算器重载了" , , 三个运算符 实现计数器加1, 和取值的操作. 实现计数器加 ,减1和取值的操作. 和取值的操作
operator 为关键字; 为关键字; operator@为函数名. 为函数名.
参数表列出该运算符需要的操作数.单目运算参数表中 参数表列出该运算符需要的操作数. 无参数,调用该函数的对象为操作数. 无参数,调用该函数的对象为操作数.双目运算参数表中有一 个参数,调用该函数的对象为第一操作数, 个参数,调用该函数的对象为第一操作数,参数表中的参数为 第二操作数. 第二操作数. 运算符函数体对重载的运算符的含义作出新的解释. 运算符函数体对重载的运算符的含义作出新的解释.这种 解释仅局限在重载该运算符的类中,即当在X类对象的关联中 类对象的关联中, 解释仅局限在重载该运算符的类中,即当在 类对象的关联中, 运算符含义由函数体解释;否则脱离类对象, 运算符含义由函数体解释;否则脱离类对象,该运算符具有系 统预定义的含义. 统预定义的含义.
结果: 结果: C1+C2=5-1i C1-C2=-1+1i
注意:程序中出现的表达式C1+C2中的运算符"+"的操作数是 注意:程序中出现的表达式 中的运算符" 的操作数是 中的运算符 两个复数对象,是重载的加法运算符.编译器解释为: 两个复数对象,是重载的加法运算符.编译器解释为:
C1.operator+(C2);
其中,第一操作数为this 指针指向的对象C1(重载函数的调用 其中,第一操作数为 指针指向的对象 重载函数的调用 者),第二操作数为 . ,第二操作数为C2. 同理,表达式 被编译器解释为: 同理,表达式C1-C2被编译器解释为: 被编译器解释为
C1.operator-(C2);
综上可见: 综上可见:对运算符的重载为成员函数形式时可采用隐式和显 式两种方式调用. 式两种方式调用.
inline Complex Complex::operator+(const Complex& c)
{
return Complex(real+c.real,imag+c.imag);
}
inline Complex Complex::operator-(const Complex& c)
{
return Complex(real-c.real,imag-c.image);
应用程序中的表达式
<对象A><运算符>(<实际参数>) 例:Complex A,B; A+B;
编译系统内部表示
operater<运算符>(对象A, 实际参数) 例:operater+(A,B)
运算符重载函数可以定义为友元函数的形式,格式如下: 运算符重载函数可以定义为友元函数的形式,格式如下:
void Counter::operator--( )
{ }
if(value>0)
value--;
unsigned int Counter:operator( )( )
{ }
return value;
main()
{
Counter mycounter; for(int i=0; i<12;i++)
{
//i++中的"++"是重载运算符吗? 中的" 是重载运算符吗? 中的 是重载运算符吗