Download presentation
Presentation is loading. Please wait.
Published byIda Rachman Modified 5年之前
1
第14讲 运算符重载 运算符重载的概念、方法和规则 运算符重载作为类的成员函数 运算符重载作为类的友元函数 特殊运算符的重载 类型转换函数
2
学习目标 理解运算符重载的含义和规则; 掌握运算符重载作为类成员函数和友元函数的 方法;
掌握常用运算符的重载,了解++和--等特殊运 算符的重载; 理解不同类型数据间转换的概念和方法。
3
第14讲 运算符重载 运算符重载的概念、方法和规则 运算符重载作为类的成员函数 运算符重载作为类的友元函数 特殊运算符的重载 类型转换函数
4
同一运算符作用于不同类型的数据具有不同实现
什么是运算符重载 (一)什么是重载( Overloading )? 1、重载——重新赋予新的含义 2、函数重载 3、运算符重载——为已有的运算符赋予多重含义。 int a,b,c; c=a+b; cout<<c; double x,y,z; z=x+y; cout<<z; 同一运算符作用于不同类型的数据具有不同实现
5
什么是运算符重载 int sum,a=3,b=2; (int)=(int) + (int) sum=a+b;
系统自动识别数据类型 sum=a+b; float add, x=3.2, y=2.5; (float)=(float) + (float) add=x+y; char str[4], c1[2]="a", c2[2]="b"; (char *)=(char *) + (char *) str=c1+c2; 编译系统中的运算符“+”本身不能做这种运算,若使上式可以运算,必须重新定义“+”运算符,这种重新定义的过程成为运算符的重载。
6
运算符重载的作用 class A { float x,y; public:
A(float a=0, float b=0){ x=a; y=b; } } void main(void) { A a(2,3), b(3,4), c; c=a+b; 两对象不能使用+,必须重新定义+ 通过重载可使该运算符能像操作基本数据类型一样,来操作用户自定义的数据类型。
7
运算符重载的作用 运算符的重载从另一个方面体现了面向对象编程技术的多态性,即同一运算符根据不同的运算对象可以完成不同的操作。
为了重载运算符,必须定义一个函数,并告诉编译器,遇到这个重载运算符时就调用该函数,由这个函数来完成该运算符应该完成的操作。这种函数称为运算符重载函数。
8
运算符重载的方法 { 运算符的重载处理 } 1、通过定义一个重载运算符函数来实现。 2、重载运算符函数的一般格式 3、举例
函数类型 operator 运算符 ( 形参列表 ) { 运算符的重载处理 } 3、举例 重载“+”,实现复数加法运算
9
. .* :: sizeof ? : 运算符重载的规则 只能对已有的运算符进行重载。 大部分运算符都可以重载,以下五个除外:
运算符重载后,“三不变”。 即原运算符的操作数的个数、优先级和结合性 都不变。 其他规则。P219
10
第14讲 运算符重载 运算符重载的概念、方法和规则 运算符重载作为类成员函数 运算符重载作为类的友元函数 特殊运算符的重载 类型转换函数
11
重载为类的成员函数 A opeator + (A &); 格式如下:
<类名> operator<运算符>(<参数表>) { 函数体 } 运算的对象 关键字 返回类型 函数名 运算的对象 A opeator + (A &); //重载了类A的“+”运算符 其中:operator是定义运算符重载函数的关键字,它与其后的运算符一起构成函数名。
12
利用函数完成了加法运算 用和作对象调用函数 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; } }; void main(void) { A a1(10),a2(20),a3; a1.Show (); a2.Show (); // a3=a1+a2; //不可直接运算 a3.AddA(a1,a2); //调用专门的功能函数 a3.Show (); } 没有重载运算符的例子 利用函数完成了加法运算 用和作对象调用函数
13
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=this->i+a.i; return t; } }; void main(void) { A a1(10),a2(20),a3; a1.Show (); a2.Show (); a3=a1+a2; //重新解释了加法,可以直接进行类的运算 a3.AddA(a1,a2); //调用专门的功能函数 a3.Show (); } 运用重载运算符的例子 相当于a3=a1.operator+(a2)
14
重载运算符与一般函数的比较: void AddA(A &a, A &b) { i=a.i+b.i; } A operator +(A &a)
相同:1)均为类的成员函数;2)实现同一功能 返回值 函数名 返回值 函数名 形参列表 void AddA(A &a, A &b) { i=a.i+b.i; } A operator +(A &a) { A t; t.i=this->i+a.i; return t; } 形参 函数调用: a3.AddA(a1,a2); 函数调用: 由对象a1调用 由对象a3调用 a3=a1+a2; a3=a1.operator+(a2);
15
重载为类的成员函数 重新定义运算符,由左操作符调用右操作符。最后将函数返回值赋给运算结果的对象。 A operator +(A &a)
函数名 重新定义运算符,由左操作符调用右操作符。最后将函数返回值赋给运算结果的对象。 返回值 A operator +(A &a) { A t; t.i=this->i+a.i; return t; } 形参 函数调用: 由对象a1调用 a3=a1+a2; a3=a1.operator+(a2);
16
重载为类的成员函数 当用成员函数实现运算符的重载时,运算符重载函数的参数只能有二种情况:没有参数或带有一个参数。
对于只有一个操作数的运算符(如++),在重载这种运算符时,通常不能有参数; 而对于有二个操作数的运算符,只能带有一个参数。 这时参数可以是对象,对象的引用,或其它类型的参数。在C++中不允许重载有三个操作数的运算符。
17
重载为类的成员函数 用成员函数实现运算符的重载时,运算符的左操作数为当前对象,并且要用到隐含的this指针。
18
静态成员变量 静态成员变量 类的静态成员变量是直接与类联系,属于类的成员 而不是对象,供所有对象共享,存放于全局区,因 而不计入类的内存计算。 静态成员不属于类的任何对象,所以并不是对象建 立时被定义的,所以它不能由类的构造函数初始化 ,一般也不能在类内初始化。 关键字static只出现类的内部。 可以声明为const。
19
静态成员函数 静态成员函数类似于静态成员变量都属于类而 不是对象。 静态成员函数仅可以调用类的静态成员变量, 不可以调用普通成员变量。
静态成员函数类似于静态成员变量都属于类而 不是对象。 静态成员函数仅可以调用类的静态成员变量, 不可以调用普通成员变量。 不具有this指针。 不能声明为const。
20
静态成员变量与静态成员函数 int A::ac=1;
int A::dc=1; int A::stval() { // nn=10; dc=20; return dc;} int A::val() { dc=ac; return dc; } int main() { A a; cout<<a.ac; cout<<a.val(); cout<<A::bc; cout<<A::stval(); cout<<a.stval(); return 0; } 类外定义且初始化 #include <iostream> using namespace std; class A { public: A(){} int val(); static int stval(); static int ac; const static int bc=2; private: static int dc; int nn; }; 错误,静态成员函数不能调用非静态成员 静态成员函数 静态成员变量 使用类的对象访问 类作用域运算符直接访问 常量静态成员可以在类内初始化
21
第14讲 运算符重载 运算符重载的概念、方法和规则 运算符重载作为类的成员函数 运算符重载作为类的友元函数 特殊运算符的重载 类型转换函数
22
运算符重载作为类的友元函数 友元函数是在类外的普通函数,与一般 函数的区别是可以调用类中的私有或保 护数据。
友元函数是在类外的普通函数,与一般 函数的区别是可以调用类中的私有或保 护数据。 将运算符的重载函数定义为友元函数, 参与运算的对象全部成为函数参数。
23
运算符重载作为类的友元函数 对双目运算符,友元函数有2个参数,对单目运算符,友元函数有一个参数。有些运算符不能重载为友元函数,它们是:=,(),[ ],->等。格式为: friend <函数类型> operator<运算符>(<参数表>) {......} 例如:c=a+b; // c=operator+( a, b) friend A operator + (A &a, A &b) {.....}
24
例如: A a, b, c; c=a+b; 实际上是 c=operator+(a, b); c=++a;
实际上是 operator+=( c, a );
25
void Show(void) {cout<<"i="<<i<<endl;}
class A { int i; public: A(int a=0) { i=a; } void Show(void) {cout<<"i="<<i<<endl;} friend A operator + (A &,A &);//友元函数,两个参数,为引用 }; A operator + (A &a , A &b) {A t; t.i=a.i+b.i; return t; } void main(void) { A a1(10),a2(20),a3; a1.Show (); a2.Show (); a3=a1+a2; //重新解释了加法,可以直接进行类的运算 a3.Show (); } 相当于a3=operator+(a1,a2)
26
运算符重载作为类的友元函数 class Complex { double real, imag; public:
Complex(double x=0,double y=0) { real=x; imag=y; } friend Complex operator+(Complex &c1,Complex &c2); void Display() { cout<<real<<"+"<<imag<<"i"<<endl;} };
27
运算符重载作为类的友元函数 Complex operator +(Complex &c1,Complex &c2) { Complex c;
c.real =c1.real +c2.real ; c.imag =c1.imag +c2.imag ; return c; }
28
运算符重载作为类的友元函数 等价于 c3=operator+(c1,c2); void main() {
Complex c1(1,3),c2(4,-5),c3; cout<<"c1="; c1.Display (); cout<<"c2="; c2.Display (); c3=c1+c2; cout<<"c1+c2="; c3.Display (); } 等价于 c3=operator+(c1,c2);
29
第13讲 运算符重载 运算符重载的概念、方法和规则 运算符重载作为类的成员函数 运算符重载作为类的友元函数 特殊运算符的重载 类型转换函数
30
重载++与--运算符 A a; ++a; a++; A a, b; b=++a; b=a++; 重载为类的成员函数
31
重载++与--运算符 A a, b; b=++a; b=a++; A operator ++(void){ .... }
++为前置运算时,它的运算符重载函数的一般格式为: <type> operator ++(void) { ;} ++为后置运算时,它的运算符重载函数的一般格式为: <type> operator ++(int) A a, b; b=++a; b=a++; A operator ++(void){ } A operator ++(int){ }
32
例程: class A { float x, y; public: A(float a=0, float b=0){ x=a; y=b; } A operator ++(void){A t; t.x=++ x; t.y=++y; return t;} A operator ++(int) {A t; t.x=x++; t.y=y++; return t;} }; void main(void) { A a(2,3), b; b=++a; b=a++; }
33
重载++与--运算符 重载为类的友元函数 ++为前置运算时,它的运算符重载函数的一般格式为: A operator ++(A &a)
{ ;} ++为后置运算时,它的运算符重载函数的一般格式为: A operator ++(A &a, int)
34
例如 A a, b; b=++a; b=a++; friend A operator ++( A &a ){ .... }
friend A operator ++(A &a, int){ }
35
例程 class A { int i; void main(void) public: { A a1(10),a2,a3;
A(int a=0) { i=a; } void Show(void) {cout<<"i="<<i<<endl;} friend A operator++(A &a) { a.i++; retrurn a;} friend A operator++(A &a, int n) { A t; t.i=a.i; a.i++; return t; } }; void main(void) { A a1(10),a2,a3; a2=++a1; a3=a1++; a2.Show(); a3.Show (); }
36
第14讲 运算符重载 运算符重载的概念、方法和规则 运算符重载作为类的成员函数 运算符重载作为类的友元函数 特殊运算符的重载 类型转换函数
37
类型转换函数 A float 类型转换函数就是在类中定义一个成员函数,其作用是将类转换为某种数据类型。
class A { float x, y; public: A(float a, float b){ x=a; y=b;} }; void main(void) { A a(2,3); cout<<a<<endl; } 利用转换函数将类A的对象a转换成某种数据类型 A float 错误!类的对象不能直接输出
38
A float 1.转换函数必须是类的成员函数。 在类外定义的格式为:
ClassName :: operator <type>( ) { } 关键字 欲转换类型 类名 具体的转换算法 2.转换函数的调用是隐含的,没有参数。 A :: operator float ( ) { return x+y; } 转换算法自己定义
39
例程 void main(void) class A { A a1(10),a2(20); { int i;
public:public: A(int a=0) { i=a; } void Show(void) { cout<<"i="<<i<<endl;} operator int( ){return i;} }; void main(void) { A a1(10),a2(20); cout<<a1<<endl; cout<<a2<<endl; }
40
class Complex{ float Real, Image; public: Complex(float real=0,float image=0) { Real=real; Image=image; } void Show(void) {cout<<"Real="<<Real<<'\t'<<"Image="<<Image<<endl; } operator float(); //成员函数,定义类转换 Complex->float }; Complex::operator float () { return Real*Real+Image*Image;} void main(void) { Complex c(10,20); c.Show (); cout<<c<<endl;//可以直接输出c,因为已经进行类型转换 }
41
第14讲 运算符重载 运算符重载的概念、方法和规则 运算符重载作为类的成员函数 运算符重载作为类的友元函数 特殊运算符的重载 类型转换函数
Similar presentations