类与对象的构造设计_第1页
类与对象的构造设计_第2页
类与对象的构造设计_第3页
类与对象的构造设计_第4页
类与对象的构造设计_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第6 6章章 类与对象的构造设计类与对象的构造设计n本章的学习目的本章的学习目的 与人们认识客观世界一样与人们认识客观世界一样,面向对象技术认面向对象技术认为客观世界是由各种各样的实体组成为客观世界是由各种各样的实体组成,每个实每个实体都可表示成一个对象。因此,客观世界是体都可表示成一个对象。因此,客观世界是由各种各样的对象组成,每种对象都有各自由各种各样的对象组成,每种对象都有各自的内部状态和运动规律,不同对象间相互作的内部状态和运动规律,不同对象间相互作用和联系就构成了各种不同的系统,从而形用和联系就构成了各种不同的系统,从而形成了客观世界。因此,在面向对象的程序中,成了客观世界。因此,

2、在面向对象的程序中,客观系统自然被描绘成一系列完全自治、封客观系统自然被描绘成一系列完全自治、封装的对象。由此可见,装的对象。由此可见,对象是组成面向对象对象是组成面向对象程序的基本单位。程序的基本单位。 面向对象的程序又将对象划分成类,类定义了属于面向对象的程序又将对象划分成类,类定义了属于该类的所有对象的共同特征,它可作为生成对象的一种该类的所有对象的共同特征,它可作为生成对象的一种模板,使对象成为类的实例。模板,使对象成为类的实例。 从语言角度来说,类是一种新的数据类型,是一种从语言角度来说,类是一种新的数据类型,是一种用户自定义类型,而对象是具有这种类型的变量。类是用户自定义类型,而对

3、象是具有这种类型的变量。类是一种将数据和作用于这些数据上的操作组合在一起的复一种将数据和作用于这些数据上的操作组合在一起的复杂数据类型,是可重用的基本单元。杂数据类型,是可重用的基本单元。 总之,总之,类和对象是面向对象程序设计的核心支柱,类和对象是面向对象程序设计的核心支柱,利用它们可以实现数据的抽象、数据和操作的封装以及利用它们可以实现数据的抽象、数据和操作的封装以及信息的隐蔽,是实现其他许多高级特性的基础。因此,信息的隐蔽,是实现其他许多高级特性的基础。因此,我们应该学习类和对象的定义、设计和实现方法。通过我们应该学习类和对象的定义、设计和实现方法。通过面向对象程序设计实践进一步学习和领

4、会面向对象的基面向对象程序设计实践进一步学习和领会面向对象的基本思想和方法技术。本思想和方法技术。n本章的学习内容本章的学习内容学习和掌握类的定义方法和对象的创建方法。学习和掌握类的定义方法和对象的创建方法。学习和掌握类的成员访问权限控制方法。学习和掌握类的成员访问权限控制方法。学习和掌握构造函数与析构函数的用法学习和掌握构造函数与析构函数的用法学习和掌握类的封装、可见性和引用的操作方学习和掌握类的封装、可见性和引用的操作方法法了解结构、联合的面向对象特性和用法。了解结构、联合的面向对象特性和用法。 3.1 类的构造和对象的创建类的构造和对象的创建 3.1.1 类设计的基本原则类设计的基本原则

5、 在面向对象的程序中,客观系统自然被描绘成一系列完全自治、封装的对在面向对象的程序中,客观系统自然被描绘成一系列完全自治、封装的对象象,并将这些对象划分成类,类定义了属于该类的所有对象的共同特征,它可并将这些对象划分成类,类定义了属于该类的所有对象的共同特征,它可作为生成对象的一种模板,使对象成为类的实例。作为生成对象的一种模板,使对象成为类的实例。 从整体功能层面谈类设计,有如下三条原则:从整体功能层面谈类设计,有如下三条原则:单一功能原则单一功能原则(Single Responsibility Principle)(Single Responsibility Principle)一个一个c

6、lassclass就其整体应该只提供单一的服务。如果一个就其整体应该只提供单一的服务。如果一个classclass提供多样的提供多样的服务,那么就应该把它拆分,反之,如果一个在概念上单一的功能却由几个服务,那么就应该把它拆分,反之,如果一个在概念上单一的功能却由几个classclass负责,这几个负责,这几个classclass应该合并。应该合并。开放开放/ /封闭原则封闭原则(Open/Close Principle)(Open/Close Principle)一个设计并实现好的一个设计并实现好的classclass,应该对扩充开放,而对修改封闭。即,这个,应该对扩充开放,而对修改封闭。即,

7、这个classclass应该是允许扩充的,但不允许修改。如果需要功能上的扩充,一般来说应该是允许扩充的,但不允许修改。如果需要功能上的扩充,一般来说应该通过添加新类实现,而不是修改原类的代码。添加新类不单可以通过直应该通过添加新类实现,而不是修改原类的代码。添加新类不单可以通过直接继承,也可以通过组合。接继承,也可以通过组合。最小惊讶原理最小惊讶原理(Least Surprise Principle)(Least Surprise Principle)在重载函数或者用子类实现父类虚函数时,应该基本维持函数原来所期望在重载函数或者用子类实现父类虚函数时,应该基本维持函数原来所期望的功能。的功能。

8、3.1.2 类的说明和对象的定义类的说明和对象的定义 类定义的一般格式如下类定义的一般格式如下: class class_name private: /私有成员,缺省默认值私有成员,缺省默认值 private variables and function; protected: /保护成员保护成员 protected variables and function; public: /公有成员公有成员 public variables and function; object_list;说明:说明:(1)class_name(1)class_name是类名是类名; ; (2) (2)关键字关键字

9、publicpublic、privateprivate和和protectedprotected是访问权是访问权 限修饰符,表示三种不同的访问权限。限修饰符,表示三种不同的访问权限。 (3) (3)类的成员既可包括变量,又可包括函数。类的成员既可包括变量,又可包括函数。 (4) (4) object_listobject_list为可选项,用户可在说明类之后,为可选项,用户可在说明类之后, 根据需要再定义类的对象。例如:根据需要再定义类的对象。例如: class_nameclass_name object_list;【例例3.1】 类的说明与对象定义实例类的说明与对象定义实例#include c

10、onst int SIZE=10;class stack /类名很重要类名很重要private: /私有成员部分私有成员部分 char stkSIZE; int tos;public: /公有成员部分公有成员部分 void init(); void push(char ch); char pop(); / 初始化成员变量初始化成员变量tosvoid stack : init() tos=0; /把一个字符压入栈中把一个字符压入栈中void stack : push(char ch)if(tos=SIZE) coutStack is full.n; return; stktos=ch;tos+;

11、/ 弹出一个字符弹出一个字符char stack : pop() if (tos=0) coutStack is empty.n; return 0; tos-; return stktos;int main() stack s1,s2; int i ;s1.init(); s2.init(); s1.push(a);s2.push(x);s1.push(b);s2.push(y); s1.push(c);s2.push(z);for(i=0;i3;i+) couts1.pop( )“t”;for(i=0;i3;i+) couts2.pop( )“t”;return 0;运行结果运行结果: c

12、 b a z y x3.1.3 3.1.3 成员函数的功能与定义方式成员函数的功能与定义方式 n 成员函数的功能和作用是成员函数的功能和作用是: :用于对象数据的处理操作用于对象数据的处理操作, , 实现对象的操作行为,为外部程序提供操作接口。实现对象的操作行为,为外部程序提供操作接口。n成员函数的定义方式有两种:成员函数的定义方式有两种:(1)(1)外置方式外置方式:成员函数的声明在类的说明体内,成员函:成员函数的声明在类的说明体内,成员函数的定义则在类外。如上例。注意:数的定义则在类外。如上例。注意: (a)(a)在函数名前标明类属,形式是:在函数名前标明类属,形式是:return_ ty

13、pe return_ type class_nameclass_name : :function_namefunction_name ( (para_listpara_list ) ) (b) (b)函数返回类型与类说明中的类型一致。函数返回类型与类说明中的类型一致。 (c) (c)显式指明函数参数的类型和名字。显式指明函数参数的类型和名字。(2)(2)内置方式内置方式:成员函数的声明和定义均在类的说明体内。:成员函数的声明和定义均在类的说明体内。n内置和外置的处理规则:内置和外置的处理规则:对于比较小的成员函数,在类对于比较小的成员函数,在类的说明体内定义,的说明体内定义,有助于减少调用开销

14、,提高运行速度;有助于减少调用开销,提高运行速度;而对比较大成员函数,则在类体外定义,这样可以减少而对比较大成员函数,则在类体外定义,这样可以减少程序代码的长度。根据实际需要来决定。程序代码的长度。根据实际需要来决定。 /内置方式举例内置方式举例#include const int SIZE=10;class stack /类名很重要类名很重要private: /私有成员部分私有成员部分 char stkSIZE; int tos;public: /公有成员部分公有成员部分 void init() tos=0; /内置定义内置定义 void push(char ch); char pop();

15、 void test() x=pop(); ; 3.1.4 3.1.4 对类成员的访问对类成员的访问类成员访问的原则是:类成员访问的原则是: (1)(1)成员函数可直接访问同类中的成员变量和成员函数可直接访问同类中的成员变量和调用同类中的成员函数,不用在函数名前加上调用同类中的成员函数,不用在函数名前加上对象名。因为公用成员的作用域是不但包括类对象名。因为公用成员的作用域是不但包括类说明体,还包括它所属对象的可视范围(静态说明体,还包括它所属对象的可视范围(静态成员除外);私有成员或受保护成员的作用域成员除外);私有成员或受保护成员的作用域仅限于类的说明体和类的成员函数。仅限于类的说明体和类的

16、成员函数。 (2) (2)可以在类外访问公用成员,但必须在成员可以在类外访问公用成员,但必须在成员名前加上对象名。名前加上对象名。int main() stack s1,s2; int i ;/在类外访问公用成员在类外访问公用成员 s1.init(); s2.init(); s1.push(a);s2.push(x);s1.push(b);s2.push(y); s1.push(c);s2.push(z);for(i=0;i3;i+) couts1.pop( )“t”;for(i=0;i3;i+) couts2.pop( ) 上一页|下一页第4页/共4页所使用的关键字所使用的关键字访问权限访问

17、权限public (公有成员公有成员)可以为类的成员函数、友元函可以为类的成员函数、友元函数和外部的所有函数所访问数和外部的所有函数所访问protected(受保护成员)(受保护成员)只能为类的成员函数和只能为类的成员函数和友元函数所访问友元函数所访问private(私有成员)(私有成员)只能为类的成员函数和只能为类的成员函数和 友元函数所访问友元函数所访问 3.2 3.2 构造函数和析构函数构造函数和析构函数 n在在OOPOOP中,创建对象时都需要作某种形式的初始化,为此,在中,创建对象时都需要作某种形式的初始化,为此,在C+C+的类说明中,引进了构造函数(的类说明中,引进了构造函数(con

18、structor functionconstructor function),),供创建类的实例对象时调用,并自动完成对象的初始化。例如供创建类的实例对象时调用,并自动完成对象的初始化。例如: : class stack char stkSIZE;int tos;public:stack( ); /这是一个构造函数这是一个构造函数void push(char ch);char pop( );stack:stack( ) cout “Constructing a stack.n”;tos=0; /初始化初始化 int main() stack s1,s2;3.2.1 构造函数的特性构造函数的特性

19、构造函数具有以下特性:构造函数具有以下特性:(1)(1)构造函数的名称与它所属的类名相同,且是构造函数的名称与它所属的类名相同,且是无返回值类型。无返回值类型。 (2)(2)一个类可以有一个以上的构造函数,重载构一个类可以有一个以上的构造函数,重载构造函数参数个数或类型不一样。如果编程时在类造函数参数个数或类型不一样。如果编程时在类中没有显式定义构造函数,则编译器会为类自动中没有显式定义构造函数,则编译器会为类自动生成一个缺省构造函数,缺省构造函数不带任何生成一个缺省构造函数,缺省构造函数不带任何参数。参数。 (3)(3)构造函数是在用类定义对象时,由编译器自构造函数是在用类定义对象时,由编译

20、器自动调用的。构造函数与一般成员函数性质相同,动调用的。构造函数与一般成员函数性质相同,同样要受到访问限制,一个定义于非同样要受到访问限制,一个定义于非publicpublic区的区的构造函数说明该类为私有类。构造函数说明该类为私有类。 【例例3.2】 私有类实例私有类实例#include “iostream.h”class test private: int i; static int number; test(int a) i=a;/该构造函数为私有,在类外不可访问该构造函数为私有,在类外不可访问 public: void show(); static void count(); int

21、test:number=0; inline void test:show() couti; void test:count() test obj1(number);/虽然构造函数为私有,但它对成员函数仍是可见的。虽然构造函数为私有,但它对成员函数仍是可见的。 number+; obj1.show();void main() test an_object; /此句是错误的,因为没有公有此句是错误的,因为没有公有 /的构造函数,就无法在类之外创建对象。的构造函数,就无法在类之外创建对象。for(int j=0;j5;j+) test:count(); coutt; 3.2.2 3.2.2 构造函数

22、的设计和使用构造函数的设计和使用 3.2.2.13.2.2.1 带参数的构造函数带参数的构造函数 例例3.3 带参数的构造函数带参数的构造函数 class pointer int x,y;public: pointer(int cx, int cy); void offset(int ox,int oy);pointer:pointer(int cx, int cy)x=cx; /用参数对变量作初始化用参数对变量作初始化y=cy;void pointer:offset(int ox,int oy)x=x+ox; /私有变量增值私有变量增值y=y+oy;void main( )pointer p

23、t1(20,30);/定义对象时初始化定义对象时初始化/也可采用下面语法形式:也可采用下面语法形式:pointer pt1=pointer(20,30);pt1.offset(40,35);/如上句无参,则本句无效如上句无参,则本句无效n 构造函数常常使用缺省值,因为如果构造函数定义构造函数常常使用缺省值,因为如果构造函数定义了缺省值,在函数调用时,若无特别指定参数,便了缺省值,在函数调用时,若无特别指定参数,便可用缺省值作初始化。而且也可防止遗漏初始赋值。可用缺省值作初始化。而且也可防止遗漏初始赋值。例如例如:可将上述函数改为可将上述函数改为带缺省参数的构造函数带缺省参数的构造函数 。cla

24、ss pointerint x,y; public:pointer(int cx=0,int cy=0) x=cx; y=cy; ;void main( )pointer pta; /实际是实际是x=0,y=0/ 由于定义了缺省参数,调用时允许不带参数由于定义了缺省参数,调用时允许不带参数pointer ptb(20);/实际是实际是x=20,y=0pointer ptc(30,40); /实际是实际是x=30,y=40n如果函数调用时的实参个数不足,编译器将优先匹配前如果函数调用时的实参个数不足,编译器将优先匹配前面的形参,而不管前面的形参是否有缺省值。例如,某面的形参,而不管前面的形参是否

25、有缺省值。例如,某函数原型为函数原型为func(intfunc(int a,inta,int b=0,int c=2) b=0,int c=2),它有,它有3 3个参个参数。若调用时采用:数。若调用时采用:func(3,5)func(3,5) 的形式,则编译器将的形式,则编译器将理解为:理解为: a=3,b=5,c=2; a=3,b=5,c=2; /自动匹配前两个形参,自动匹配前两个形参,b b不用缺省值,不用缺省值,c c使用了缺省值使用了缺省值2 2。 因此,如果最后若干个参数没有缺省值,而调用时参数因此,如果最后若干个参数没有缺省值,而调用时参数又不够,则会发生参数不足的错误。又不够,则

26、会发生参数不足的错误。 n构造函数的构造函数的缺省参数只能在参数表的后面定义。例如:缺省参数只能在参数表的后面定义。例如: 1) boy(int x,int y=0); /正确正确2) boy(int x=0,int y); /错误错误3) fun(int i,int j,int k=99);/正确正确4) fun(int i,int j=88,int k);/错误错误 n当构造函数只有一个参数时,可采用以下形式来定义当构造函数只有一个参数时,可采用以下形式来定义对象:对象: class_nameclass_name obj_nameobj_name=value;=value;例如:例如:cl

27、ass myclass int a;public: myclass(int j) a=j; / ; .void main( ) myclass obj=2008; /在一个参数的情况下可以使用这在一个参数的情况下可以使用这 / 种形式,种形式, 将初始值传递给对象将初始值传递给对象 3.2.2.23.2.2.2多构造函数多构造函数 对于一个类的不同对象对于一个类的不同对象, ,当需要不同类型和个数当需要不同类型和个数的初始化参数时的初始化参数时, ,可以在一个类中定义几个构造可以在一个类中定义几个构造函数。函数。 例如例如 class class dtldtl ; ; public: publ

28、ic: dtdt obj1(); obj1(); dtdt obj2(int); obj2(int); dtdt obj3(int,char); obj3(int,char); dtdt obj4(float,int); obj4(float,int); ; ; n 所定义的多个构造函数之间,在参数个数或数据类所定义的多个构造函数之间,在参数个数或数据类型上必须有差异。在定义对象时,使用缺省参数调用型上必须有差异。在定义对象时,使用缺省参数调用多构造函数时,要特别注意二义性。多构造函数时,要特别注意二义性。例如:例如: class class dtldtl ; ; public: public

29、: dtdt();(); dt(intdt(int arar=0);=0); ; ; void main() void main() dtldtl ob1(33); ob1(33); /与与 dtl(intdtl(int) )相匹配相匹配 dtldtl ob2; ob2; /发生发生二义性错误二义性错误 ; ; 3.2.2.3 复制构造函数复制构造函数n复制构造函数是一种特殊的构造函数,它的功能是复制构造函数是一种特殊的构造函数,它的功能是用一个已知的对象来初始化一个被定义的同类的对用一个已知的对象来初始化一个被定义的同类的对象。象。 n复制构造函数的定义格式如下:复制构造函数的定义格式如下:

30、class public: (); / 构造函数构造函数 (const & ); /拷贝构造拷贝构造 ;:(const & ) /拷贝构造函数的实现拷贝构造函数的实现 class pointerclass pointer intint x,yx,y; ; public: public: pointer(intpointer(int cx,intcx,int cy)xcy)x= =cxcx; y=cy; y=cy; pointer(constpointer(const pointer &p) pointer &p) x= x=p.xp.x; y=; y=p.yp.y; ; ; ;void mai

31、n()void main() pointer ob1(40,50); pointer ob1(40,50); pointer ob2=ob1; pointer ob2=ob1; n 浅复制与深复制浅复制与深复制(1)浅复制浅复制:在用一个对象初始化另一个对象时在用一个对象初始化另一个对象时,如果只复如果只复制了成员制了成员,并没有复制资源并没有复制资源,使两个对象同时指向了同一使两个对象同时指向了同一资源的复制方式称为浅复制资源的复制方式称为浅复制,如图如图(a)所示。所示。(2)深复制深复制:在用一个对象初始化另一个对象时在用一个对象初始化另一个对象时,如果不仅如果不仅复制了成员复制了成员,

32、也复制了资源也复制了资源,则这种复制方式称为深复制则这种复制方式称为深复制,如图如图(b)所示。所示。n 如果在类中没有显式定义复制构造函数如果在类中没有显式定义复制构造函数,则用一个对则用一个对象初始化另一个对象时只能用编译器提供的缺省复制象初始化另一个对象时只能用编译器提供的缺省复制构造函数来进行浅复制;否则可用显式定义的复制构构造函数来进行浅复制;否则可用显式定义的复制构造函数来进行深复制。造函数来进行深复制。(3)(3)如果类中包含指针成员且在创建一个对象时需要动如果类中包含指针成员且在创建一个对象时需要动态分配内存资源态分配内存资源, ,则必须显式定义复制构造函数,以则必须显式定义复

33、制构造函数,以实现深复制。如果在类中不显式定义复制构造函数实现深复制。如果在类中不显式定义复制构造函数, ,则用一个对象初始化另一个对象时只能用编译器提则用一个对象初始化另一个对象时只能用编译器提供的缺省复制构造函数来进行浅复制,就会使两个供的缺省复制构造函数来进行浅复制,就会使两个对象的成员指针指向同一个内存区,当一个指针被对象的成员指针指向同一个内存区,当一个指针被释放以后,另一个指针就会悬空,出现错误。释放以后,另一个指针就会悬空,出现错误。 3.2.3 析构函数的特性和用法析构函数的特性和用法析构函数也是成员函数,与构造函数相对应,析构函数也是成员函数,与构造函数相对应,命名是在构造类

34、名前加命名是在构造类名前加 ( (波浪线波浪线) )。 析构函数只能是无返回值类型。析构函数只能是无返回值类型。 析构函数不能有任何参数。析构函数不能有任何参数。 析构函数不能重载,一个类只允许有一个析析构函数不能重载,一个类只允许有一个析构函数。构函数。 当对象离开其有效范围,或被取消时,析当对象离开其有效范围,或被取消时,析构函数将被调用来释放对象所占用的内存。构函数将被调用来释放对象所占用的内存。因此,析构函数的定义,一般是由一系列的因此,析构函数的定义,一般是由一系列的deletedelete组成。组成。 #includeclass sampleprivate:char *pointe

35、r_char;public:sample()pointer_char=NULL; ;sample(sample &ob) pointer_char =new char strlen(ob. pointer_char)+1;strcpy(pointer_char,ob.pointer_char);sample() if(pointer_char!=NULL) delete pointer_char ; 3.3 3.3 类的静态成员和动态存储分配类的静态成员和动态存储分配n静态成员静态成员是类的所有对象共享的成员,而不是类的所有对象共享的成员,而不是某个对象所特有的成员,是属于整个类的是某个对象所

36、特有的成员,是属于整个类的成员。它是为解决同一个类的不同对象之间成员。它是为解决同一个类的不同对象之间数据和函数的共享而设计的。数据和函数的共享而设计的。n静态成员静态成员分为分为静态数据成员静态数据成员和和静态成员函数静态成员函数。 其定义格式为:其定义格式为: staticstatic ;n静态成员函数是被一个类中所有对象共享的成员函静态成员函数是被一个类中所有对象共享的成员函数,不属于某个特定对象。因此,一般只用于访问数,不属于某个特定对象。因此,一般只用于访问静态数据成员或全局变量。静态数据成员或全局变量。 n调用静态成员函数,可以在其名字前面加类名或对调用静态成员函数,可以在其名字前

37、面加类名或对象名,但使用对象名容易令人产生混淆,故不鼓励象名,但使用对象名容易令人产生混淆,故不鼓励使用。使用。例例3.4 静态成员的定义方法静态成员的定义方法/student.h#include #include class Studentprotected: static int total; char name11; public: Student(char* pname=“no name”); Student(); static int number() return total; Student:Student(char* pname) cout“create one student

38、”endl; strcpy(name,pname); total+; /每创建一个对象每创建一个对象,学生人数增学生人数增1 couttotalendl;Student:Student() cout“destruct one student”endl; total-; /每析构一个对象每析构一个对象,学生人数减学生人数减1 couttotalendl;【例例3.5】 带有静态成员的类的实例带有静态成员的类的实例 #include class MyClassprivate: static int m_Count; public: static int get_Count() return m_C

39、ount; ; static void Add() m_Count+; ; ;int MyClass:m_Count=0;/必须在类外进行初必须在类外进行初void main()coutCount=MyClass:get_Count()endl; for(int j=0;j4;j+)MyClass:Add();coutCount=MyClass:get_Count()endl; 3.3.2 对象的动态存储分配对象的动态存储分配n在在C C中,内存动态分配和释放用函数中,内存动态分配和释放用函数mallocmalloc ( ) ( ) 和和free ( )free ( );而在;而在C+C+中,

40、通常使用中,通常使用newnew和和deletedelete。nnewnew运算符的三种常用格式:运算符的三种常用格式:格式格式1 1: =new =new 功能:分配一块与功能:分配一块与 相适应的存储空间,相适应的存储空间,若分配成功,将这块内存空间的首地址存入指若分配成功,将这块内存空间的首地址存入指针变量,否则置指针变量的值为针变量,否则置指针变量的值为NULLNULL(空指针(空指针值,即值,即0 0)。)。格式格式2 2: =new =new ( )功能:分配一块与功能:分配一块与 相适应的存储空间,并相适应的存储空间,并用用 为分配好的存储空间置初值。若分配成为分配好的存储空间置

41、初值。若分配成功,将这块内存空间的首地址存入指针变量,否功,将这块内存空间的首地址存入指针变量,否则置指针变量的值为则置指针变量的值为NULLNULL(空指针值,即(空指针值,即0 0)例如:例如: intint * *p;p; p=new int(100); p=new int(100); /动态存储分配一个整数单元,动态存储分配一个整数单元, /并给它赋初值并给它赋初值100100。格式格式3 3: =new =new 功能:申请大小为功能:申请大小为 的数组空间的数组空间 。但。但创建数组时,不能为该数组指定初始值。创建数组时,不能为该数组指定初始值。 例如:例如:intint * *p

42、;p; p=new int10; p=new int10; /动态分配一个含动态分配一个含 /有有1010个整数的数组个整数的数组。ndeletedelete运算符的二种常用格式:运算符的二种常用格式:格式格式1 1:delete delete 功能:释放功能:释放 指向的动态存储空间。指向的动态存储空间。 例如:例如: delete p;delete p;格式格式2 2:delete delete 功能:用于释放数组占用的动态存储空间。功能:用于释放数组占用的动态存储空间。 例如:例如:intint * *p;p; p=new int10; p=new int10; delete p; de

43、lete p;使用的语法格式使用的语法格式使用方法列举使用方法列举pointer_var = new var_type ;delete pointer_var ; int *p;p=new int;int *q;q=new int(1999); /初始化初始化float *f;f=new float15; /为一维数为一维数组分配动态内存组分配动态内存delete f; #includeclass point int x,y ;public :point(int cx=0,int cy=0) x=cx; y=cy;void print () coutx yn; ;int main( ) poi

44、nt *pp;pp=new point(20,30); /分配空间,调用构造函数进行初始化分配空间,调用构造函数进行初始化if (!pp) cout print( );delete pp;return 1; 3.4 3.4 友元友元 3.4.13.4.1友元的定义友元的定义n 根据封装性,如果将类中的数据成员声明为私有根据封装性,如果将类中的数据成员声明为私有成员,外部可以通过类的公有成员函数对私有成员进成员,外部可以通过类的公有成员函数对私有成员进行访问。但有时类体外的一些函数需要直接访问类的行访问。但有时类体外的一些函数需要直接访问类的数据成员,又不改变其数据成员的访问权限,这时,数据成员,又不改变其数据成员的访问权限,这时,需要把那些函数定义成友元。需要把那些函数定义成友元。n友元不是类的成员,但可以访问类中所有成员。友元不是类的成员,但可以访问类中所有成员。n友元通常是一个普通函数或者另一个类的成员函数或友元通常是一个普通函数或者另一个类的成员函数或者类者类。n友元可以避免频繁调用类的接口函数,提高了

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论