Download presentation
Presentation is loading. Please wait.
Published byΑἴαξ Σαμαράς Modified 5年之前
1
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
2
第6章 类和对象(二) 对象指针和对象引用 对象数组和对象指针数组 常类型 子对象和堆对象 类型转换 类模版 应用实例——链表
第6章 类和对象(二) 对象指针和对象引用 对象数组和对象指针数组 常类型 子对象和堆对象 类型转换 类模版 应用实例——链表 东华大学信息科学与技术学院 龚涛
3
第6章 类和对象(二) 6.1 对象指针和对象引用 6.1.1 指向类的成员的指针
第6章 类和对象(二) 6.1 对象指针和对象引用 指向类的成员的指针 在C++语言中,指向类的成员的指针包括指向类的数据成员和成员函数的两种指针。 指向类的成员的指针格式如下: <类型说明符> <类名>:: * <指针名> 指向成员函数的指针格式如下: <类型说明符> (<类名>:: * <指针名>)(<参数表>)。 使用指向对象的指针通过指向类成员的指针对该成员进行操作时,可使用运算符->*。 给指向函数的指针赋值的格式如下: <指向函数的指针名>=<函数名> 东华大学信息科学与技术学院 龚涛
4
6.1 对象指针和对象引用 6.1.2 对象指针和对象引用作为函数参数 对象指针作为函数参数
6.1 对象指针和对象引用 对象指针和对象引用作为函数参数 对象指针作为函数参数 使用对象指针作为函数参数要比使用对象作为函数参数更普遍一些。因为使用对象指针作为函数参数有如下两个特点: (1) 实现传址调用 (2) 使用对象指针作为形参仅将对象的地址值传给形参,而不进行对象副本的复制,这样可以提高运行效率,减少时空开销。 对象指针作为函数形参时,要求调用函数的实参是对象的地址值。 对象引用作为函数参数 在实际中,使用对象引用作函数参数要比使用对象指针作为函数更普遍。这是因为使用对象引用作为函数参数具有用对象指针作函数参数的优点,而用对象引用作为函数参数将更简单,更直接。 东华大学信息科学与技术学院 龚涛
5
6.1 对象指针和对象引用 this指针 this是一个由系统自动提供的指向对象的特殊指针,该指针是一个指向正在对某个成员函数操作的对象的指针。 当对一个对象调用成员函数时,编译程序先将对象的地址赋给系统创建的this指针,然后调用成员函数,每次成员函数存取数据成员时,都隐含使用this指针。同样,也可以使用* this来标识调用该成员函数的对象。 东华大学信息科学与技术学院 龚涛
6
第6章 类和对象(二) 6.2 对象数组和对象指针数组 6.2.1 对象数组
第6章 类和对象(二) 6.2 对象数组和对象指针数组 对象数组 对象数组是指数组元素为对象的数组。该数组中若干个元素必须是同一个类的若干个对象。对象数组的定义、赋值和引用与普通数组一样,只是数组的元素与普通数组不同,它是同类的若干个对象。 对象数组定义格式如下: <类名> <数组名>[<大小>]… 对象数组可以被赋初值,也可以被赋值。 对象数组元素的下标也是从0开始。对象数组的赋值和一般数组的赋值一样,也是给每个元素赋值。 东华大学信息科学与技术学院 龚涛
7
6.2 对象数组和对象指针数组 6.2.2 指向数组的指针和指针数组 指向数组的指针和指针数组是两个完全不同的概念,现在有必要区分。
6.2 对象数组和对象指针数组 指向数组的指针和指针数组 指向数组的指针和指针数组是两个完全不同的概念,现在有必要区分。 指向数组的指针 指向一般数组的指针定义格式如下: <类型说明符> (* <指针名>)[<大小>]… 其中,用来说明指针的*要与<指针名>括在一起。后面用一个方括号表示该指针指向一维数组,后面用两个方括号表示二维数组。<类型说明符>用来说明指针所指向的数组的元素的类型。 指向对象数组的指针定义格式如下: <类名> (* <指针名>)[<大小>]… 指针数组 数组元素为指针的数组称为指针数组。一个数组的元素可以是指向同一类型的一般指针,也可以是指向同一类型的对象指针。 东华大学信息科学与技术学院 龚涛
8
6.2 对象数组和对象指针数组 6.2.3 带参数的main()函数
6.2 对象数组和对象指针数组 带参数的main()函数 在实际编程中,有时需要main()函数带参数,通过main()函数的参数给程序增加一些处理信息。一般地说,如果使用C++语言编写的源程序经过编译连接生成的可执行文件在执行时,需要带命令行参数,则该源程序的主函数main()就需要带参数。使用所带有的参数存放命令行中的参数,以便在程序中对命令行参数进行处理。 带有参数的main()函数头格式如下: void main(int argc, char *argv[]) 其中,第一个参数argc是int型的,它用来存放命令行参数的个数,实际上argc所存放的数值比命令行参数的个数多1,即将命令字也计算在内。第二个参数argv是一个一维的一级指针数组,它是用来存放命令行中各个参数和命令字的字符串的,并且规定: argv[0]存放命令字 argv[1]存放命令行中的第一个参数 argv[2]存放命令行中的第二个参数 … argc的值和argv[各元素的值都是系统自动给赋值的。 东华大学信息科学与技术学院 龚涛
9
第6章 类和对象(二) 6.3 常类型 6.3.1 一般常量和对象常量
第6章 类和对象(二) 6.3 常类型 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。因此,定义或说明常类型量时必须进行初始化。 一般常量和对象常量 一般常量是指简单类型的常量。这种常量在定义时,修饰符const可以用在类型说明符前,也可以用在类型说明符后。定义或说明一个常数组可采用如下格式: <类型说明符> const <数组名>[<大小>]…=<初值> 或者 const <类型说明符> <数组名>[<大小>]…=<初值> 常对象是指对象常量,定义格式如下: <类名> const <对象名>(<初值>) 定义常对象时,同样要进行初始化,并且该对象不能再被更新。 东华大学信息科学与技术学院 龚涛
10
6.3 常类型 6.3.2 常指针和常引用 地址值是常量的常指针是一种指向某类型变量的常量指针,它的定义格式如下:
6.3 常类型 常指针和常引用 常指针使用修饰符const说明。有两种含意不同的常指针,一种表示指针的地址值是常量,另一种表示指针所指向的量是常量。这两种常指针的定义格式也不同。 地址值是常量的常指针是一种指向某类型变量的常量指针,它的定义格式如下: <类型> *const <指针名>=<初值> 地址值为常量的常指针所指向的量是可以改变的,而地址值是不可改变的。 所指向的值是常量的常指针是一种指向某类型常量的指针,它的定义格式如下: const <类型> * <指针名>=<初值> 使用const修饰符也可以说明引用,被说明的引用为常引用,该引用所引用的对象不能被更新。其定义格式如下: const <类型说明符> & <引用名>=<初值> 在实际应用中,常指针和常引用往往用来作为函数的形参,这样的参数称为常参数。 东华大学信息科学与技术学院 龚涛
11
6.3 常类型 常成员函数 使用const关键字进行说明的成员函数,称为常成员函数。只有常成员函数才有资格操作常量或常对象,没有使用const关键字说明的成员函数不能用来操作常对象。 常成员函数的说明格式如下: <类型说明符> <函数名>(<参数表>) const; 其中,const是加在函数说明后面的类型修饰符。它是函数类型的一个组成部分,因此,在函数实现部分也要带const关键字。 常成员函数表明this指针是常量,即this所指向的对象是不可改变的。 常对象必须用常成员函数,不能用非常成员函数;而非常对象可用非常成员函数,也可以用常成员函数。 东华大学信息科学与技术学院 龚涛
12
6.3 常类型 常数据成员 类型修饰符const不仅可以说明成员函数,也可以说明数据成员。 由于const类型对象必须被初始化,并且不能更新。因此,在类中说明const数据成员时,只能通过构造函数成员初始化列表的方式来对数据成员进行初始化。 东华大学信息科学与技术学院 龚涛
13
第6章 类和对象(二) 6.4 子对象和堆对象 子对象 当一个类的成员是某一个类的对象时,该对象就为子对象。子对象实际就是对象成员。子对象反映出了两个类之间的包含关系,又称为组合关系。这是将复杂问题分解为若干个简单问题时所采用的一种方法。 在类中出现了子对象或称对象成员时,该类的构造函数要包含子对象的初始化,通常采用成员初始化表的方法来初始化子对象。在成员初始化表中包含对子对象的初始化和对类中其他成员的初始化。 东华大学信息科学与技术学院 龚涛
14
P195 三、2. 上机验证讲解 #include <iostream.h> class B { public: B(){}
A::A(int i, int j):c(i,j) {} void A::printa() { c.printb(); } B::B(int i, int j) a=i; b=j; void B::printb() cout<<"a="<<a<<",b="<<b<<endl; void main() A m(7,9); m.printa(); #include <iostream.h> class B { public: B(){} B(int i, int j); void printb(); private: int a, b; }; class A A(){} A(int i, int j); void printa(); B c; 东华大学信息科学与技术学院 龚涛
15
6.4 子对象和堆对象 6.4.2 堆对象 new运算符的功能是创建堆对象,即动态创建对象。使用new运算符创建一个对象的格式如下:
6.4 子对象和堆对象 堆对象 所谓堆对象是指在程序运行过程中根据需要随时可以建立或删除的对象,堆对象又称为动态对象。这种堆对象被创建在内存一些空闲的存储单元中,这些存储单元称为堆。它们可以被创建的堆对象占有,也可以通过删除堆对象而获得释放。创建或删除堆对象时,需要两个运算符new和delete,这两个运算符又称为动态分配内存空间运算符。new相当于C语言中的malloc()函数,delete相当于C语言中的free()函数。 new运算符的功能是创建堆对象,即动态创建对象。使用new运算符创建一个对象的格式如下: new <类型说明符>(<初始值表>) 它表明在堆中创建一个由<类型说明符>给定的类型的对象,并且由括号中<初始值表>给出被创建对象的初始值。如果省去括号和括号中的初始值,则被创建的对象选用默认值或无效值。 使用new运算符创建对象数组的格式如下: new <类名>[<算术表达式>] delete运算符的功能是删除使用new创建的对象,其格式如下: delete <指针名>; 运算符delete也可用来删除使用new创建的对象数组,其使用格式如下: delete[] <指针名>; 东华大学信息科学与技术学院 龚涛
16
第6章 类和对象(二) 6.5 类型转换 6.5.1 类型的自动隐式转换 C++语言编译系统提供的内部数据类型的自动隐式转换规则如下:
第6章 类和对象(二) 6.5 类型转换 类型转换可将一种类型的值映射为另一种类型的值,类型转换分为自动隐式转换和强制转换两种类型。 类型的自动隐式转换 C++语言编译系统提供的内部数据类型的自动隐式转换规则如下: (1) 程序在执行算术运算时,低类型可以转换为高类型。 (2) 在赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给它。 (3) 在函数调用时,将实参值赋给形参,系统隐式地将实参转换为形参的类型后,赋给形参。 (4) 函数有返回值时,系统将自动将返回表达式的类型转换为函数类型后,赋值给调用函数。 东华大学信息科学与技术学院 龚涛
17
6.5 类型转换 构造函数具有类型转换功能 在实际应用中,当类定义中提供了单个参数的构造函数时,该类便提供了一种将某种数据类型的数值或变量转换为某种类类型的方法。因此,可以说单个参数的构造函数提供了数据类型转换的功能。 如果想要节省对构造函数进行调用所付出的开销,也可以定义一个赋值运算符重载作为类的一个成员函数,其形式如下: A& A::operator=(int i) { m=i; return *this; } 东华大学信息科学与技术学院 龚涛
18
例6.19的改进(一) #include <iostream.h> class A { public: A() { m=0;}
A(double i) { m=i;} void print() { cout<<m<<endl;} A& operator =(int i); private: double m; }; A& A::operator=(int i) { m=i; return *this; } void main() A a(5); a=10; a.print(); 东华大学信息科学与技术学院 龚涛
19
例6.19的改进(二) #include <iostream.h> class A { public: A() { m=0;}
A(double i) { m=i;} void print() { cout<<m<<endl;} A operator =(int i); private: double m; }; A A::operator=(int i) { m=i; return *this; } void main() A a(5); a=10; a.print(); 东华大学信息科学与技术学院 龚涛
20
6.5 类型转换 6.5.3 类型转换函数 转换函数又称为类型强制转换成员函数,它是类中的一个非静态成员函数。它的定义格式如下:
6.5 类型转换 类型转换函数 转换函数又称为类型强制转换成员函数,它是类中的一个非静态成员函数。它的定义格式如下: class <类型说明符1> { public: operator <类型说明符2>(); … } 这个转换函数定义了由<类型说明符1>到<类型说明符2>之间的映射关系。可见,转换函数可将某种类类型的数据转换为所指定的某种数据类型。 东华大学信息科学与技术学院 龚涛
21
第6章 类和对象(二) 6.6 类模板 类模版的引进 引进类模板的目的与引进函数模版的目的一样,就是为了更好地进行代码重用,即按照不同的方式重复使用相同的代码。为了实现代码重用,就需要使得重用的代码是通用的,即不受类型和操作的影响。类模板是C++语言支持参数化的一种工具。使用类模版所定义的一种类类型,类中的某些数据成员和某些成员函数的参数及返回值可以选取一定范围内的多种类型,从而实现代码重用。 类模板的定义格式如下: template <模版参数表> class <类名> { <类体说明> }; //类体实现 模版参数的形式如下: class <标识符> 使用模版类说明或定义对象的格式如下: <模版类名> <对象名> 类模板是一个类型参数化的样板,它是一组模版类的集合。模版类的某个类模板的实例。使用某种类型来替换某个类模版的模版参数可生成该类模板的一个模版类。 东华大学信息科学与技术学院 龚涛
22
第6章 类和对象(二) 6.7 应用实例-链表 为了更好地掌握学过的知识,应该多读一些程序和多编一些程序,这样可以掌握一些编程的方法和技巧,提高编程能力。 以单向链表为例,先建立一个链表项,作为一个类,其名为Item。它主要包含两个成员:一个是数据项data;另一个是指针*next,这是最简单的链表项,指针next用来链接下一个链表项。它只有一个数据项,用来存放数据的,实际中的链表项可以有多个数据项。 再建立一个有关链表操作的类,其类名为List。它包含如下各种操作: 显示输出一个已生成的链表; 对一个空表插入链表项,插入的新表项被放在表头,即前插入; 对一个空表追加链表项,追加的新表项被放在表尾部; 两个链表相连接,即将一个链表接在另一个链表的后面; 将一个链表的各链表项逆向输出; 求得一个链表的数据项数。 东华大学信息科学与技术学院 龚涛
23
答疑联系信息 办公室电话: 手机: 办公室地址:2号学院楼216室 东华大学信息科学与技术学院 龚涛
Similar presentations