1、C+语言程序设计,-第6章 类,第6章 类,本章学习要点,类和对象的概念及其关系 类的声明和对象的定义及使用 构造函数与析构函数的作用及使用 类成员的多种形式:成员对象,静态类成员和常量类成员 封装的破坏友员:友员函数&友员类 对象数组 对象与指针,第6章 类,本章学习目标,正确理解类、对象及封装的概念 熟练掌握类的声明和对象的定义及使用 理解构造函数与析构函数的作用及使用 掌握对象与指针及const的特点及使用 掌握静态类成员的定义与使用 了解友元函数的概念,掌握友元函数的定义与使用;了解友元类的概念,6.1 类的引入,局部变量(函数体内) 共享变量(参数和返回值) 全局变量(共享多个数据)
2、 静态全局变量(局限于文件) 文件可被视为模块(有数据及操作,隐藏数据) 文件模块不能用来生成多个同种模块; 结构可以,但任何外部函数可直接修改结构数据,类,class 类名 public:公用成员 protected:受保护成员 private:私有成员 ;,声明类的一般形式:,声明类的关键字,合法标识符,公用成员限定符,受保护成员限定符,私有成员限定符,类结束要加分号,6.2 类定义,class stack private:char v100;char *p;public:char pop( )/char push( )/ ;,6.2 类定义,【例6-1】声明一个学生类,要求包括学生的学号
3、、姓名、性别等信息,并且能够显示学生的信息。,6.2.1 类的声明,class Student /声明Student类 public: /以下部分为公用成员函数void Show() cout“No. :“stuNoendl;cout“Name:“stuNameendl;cout“Sex :“stuSexendl; private: /以下部分是私有数据成员int stuNo;char stuName20;char stuSex; ; /类声明结束,此处必须有分号,6.2.1 类的声明,1.类的成员分为数据成员和成员函数 2.成员的可访问性可分为三类:私有的(private)、受保护的(pro
4、tected)、公用的(public) 3.由访问限定符限定它后面的成员的访问属性,直到出现下一个访问限定符或者类结束为止 4.在声明类时,这三种访问属性的成员的声明次序是任意的,并且在一个类的声明中不一定这三种访问属性全部都出现,可能只出现两种或一种。 5.某个成员访问限定符在一个类的声明中也可以出现多次。,注意,6.2.1 类的声明,6.2.2 对象的定义,声明类之后,再定义对象 如:Student zhang, wang; 或:class Student zhang, wang; 在声明类的同时定义对象 如:class Student zhang, wang; 不出现类名,直接定义对象
5、如:class zhang, wang;,声明类时系统并不分配内存单元,而定义对象时系统会给每个对象分配内存单元,6.2.2 对象的定义,对象的动态创建和释放 使用new和delete运算符实现对对象的动态创建与释放; 如语句:student *stu=new student; 分配给学生对象一个存储块,并返回一个指向该对象的指针; 该对象将一直保留分配的存储,直到显示地用delete运算符删除它:delete stu;,6.2 类定义,类成员的访问(和.)void main( ) stack sta;sta.p=sta.v;sta.v1=c;sta.push(a);char ch=sta.p
6、op(); ,/ F / F / T / T,6.2 类定义,1. 对象:封装了数据及在这些数据之上的操作的封装体 2. 类:对具有相同属性和操作的一组对象的抽象描述 3. 类和对象的关系:类是对象的抽象;对象是对类的实例化 4. 一个类可以创建任意多个实例。,总结,类的优点: 可以隐藏成员,限制外部函数对它的访问,外部函数只能通过公有成员间接地访问私有数据,这就是封装。 类可以作为对象的模子,由它方便地生成多个同种对象。 封装的优点: 使类的设计者可以检查任何赋给数据成员的值的合法性,有助于避免程序设计的错误。 控制对内部数据结构的访问。使类的用户创建不依赖于特殊内部数据表达的对象。,总结,
7、6.2 类定义,class stack private:char v100;char *p;public:char pop( )/char push( )/ ;,6.3 构造函数和析构函数,6.3.1 构造函数,构造函数的作用 创建对象时对对象的数据成员初始化 构造函数的特点 构造函数是类的一个特殊的成员函数,构造函数名与类名相同,且没有返回值 构造函数不需要用户调用,由系统在创建对象时自动调用的 构造函数内容一般是初始化数据语句,但也可以是其他的语句 创建对象时肯定会执行一个构造函数,class stack /stack类定义 private: /以下部分是私有数据成员char v100;c
8、har *p;public: /以下部分为公用成员函数stack( )p=v;char pop() / push(char ch) / ; /类定义结束,6.3.1 构造函数,void main( ) stack sta; stack.push(a);char ch=sta.pop( ); ,6.3.1 构造函数,“stack sta; ”语句要做两件事: 1. 先为sta对象分配空间; 2. 调用satck的构造函数stack( )。,缺省构造函数,6.3.1 构造函数,带参数的构造函数 一般格式为:构造函数名(参数表); 实参是在定义对象时给出的,一般格式为:类名 对象名(实参表); 带参
9、数的构造函数形式可以方便的实现对不同对象进行不同的初始化 例:在创建stack类时,希望用户可以指定栈的大小?,6.3.1 构造函数,class stack private: /以下部分是私有数据成员char v100;char *p;int size;public: /以下部分为公用成员函数stack (int sz)p=new charsize=sz;v=p;char pop() / push(char ch) / ;,创建对象:stack sta(100);stack sta; /stack sta( ); /,6.3.1 构造函数,class stack private: /以下部分是
10、私有数据成员char v100;char *p;int size;public: /以下部分为公用成员函数stack (int sz=100)p=new charsize=sz;v=p; ;,创建对象:stack sta(90);stack sta;,【例6-2】 定义两个长方体,分别求出它们的体积。这两个长方体的长宽高分别是4,2,3和5,1,2。,6.3.1 构造函数,#include class Box private:float length,width,height;public:Box(float L,float w,float h) /带有参数的构造函数 length =L; w
11、idth = w; height = h; float volume() return length * width * height; ;,int main() Box box1(4,2,3); /创建对象时给出实参Box box2(5,1,2);cout“Volume of box1 is “ box1.Volume()endl;cout“Volume of box2 is “ box2.Volume()endl;return 0; ,6.3.1 构造函数,构造函数重载 在类中定义多个构造函数,这些构造函数具有相同的函数名而参数表中参数的个数或类型不同 相当于给类实例化对象时提供了不同的初
12、始化方法. 在使用重载构造函数时,应注意不要产生二义性。,6.3.1 构造函数,【例6-3】 构造函数重载。 #include class Box private:float length,width,height;public:Box() /无参数的构造函数 length = 1; width = 1; height = 1; Box(float L,float w,float h) /带有参数的构造函数 length =L; width = w; height = h; float Volume() return length * width * height; ;,int main()
13、Box box1(4,2,3); Box box2; cout“Volume of box1 is “box1.Volume()endl;cout“Volume of box2 is “box2.Volume()endl;return 0; ,6.3.1 构造函数,(1)如果在类的声明中没有写一个构造函数,系统会自动生成一个无参的、函数体为空的默认构造函数。默认构造函数只是在形式上保证创建对象时必须有构造函数。 (2) 由于一旦写了一个构造函数,系统就不再提供默认的构造函数,因此在程序中定义对象时一定要注意类中有几个构造函数,它们要求的参数分别是什么样的,如果创建对象时给出的参数表和所有的构造
14、函数的参数表都不符合,则系统无法创建对象。 (3)使用参数实例化对象时的格式是:类名 对象名(实参表);而使用默认构造函数实例化对象时的格式是:类名 对象名;,注意,6.3.2 析构函数,析构函数的作用 在系统释放对象之前进行清理工作。 析构函数的特点 析构函数的函数名是固定的,由“”+“类名”组成 析构函数没有返回值 析构函数没有参数 如果没有自己写出析构函数,系统会自动生成一个析构函数,6.3.2 析构函数,析构函数的特点 析构函数在对象生命周期结束时由系统自动调用,析构函数的作用不是释放对象,释放对象是由系统来进行的,而是在系统释放对象之前进行一些清理工作,把对象所占用的额外内存空间归还
15、给系统。,注意,6.3.2 析构函数,【例6-4】带有析构函数的长方体类。 class Box private:float length,width,height; public:Box() /无参数的构造函数 length = 1; width = 1; height = 1; Box(float L,float w,float h /带有参数的构造函数 length =L; width = w; height = h; float Volume() return length * width * height;Box() /析构函数cout“Destructor of Box is cal
16、led!“endl; ;,int main() Box box1(4,2,3);Box box2; cout“Volume of box1 is “ box1.Volume()endl;cout“Volume of box2 is “ box2.Volume()endl;return 0; ,程序执行后运行的结果如下: Volume of box1 is 24 Volume of box2 is 1 Destructor of Box is called! Destructor of Box is called!,6.3.3 构造函数和析构函数调用次序,总的原则 当创建对象时调用构造函数,当释
17、放对象时调用析构函数 创建对象是当程序执行到了非静态对象的定义语句或第一次执行到静态对象的定义语句 释放对象则是对象到了生命周期的最后时系统释放对象或通过delete运算符动态释放new运算符动态申请的对象,【例6-5】 参考例6-4,设计构造函数和析构函数,并验证其调用顺序。,6.3.3 构造函数和析构函数调用次序,6.3.3 构造函数和析构函数调用次序,int main() Box box1(4,2,3); Box box2; cout“Volume of box1 is “box1.Volume()endl;cout“Volume of box2 is “box2.Volume()end
18、l;return 0; ,程序执行后运行的结果如下: Box (4,2,3) is constructed! Box (1,1,1) is constructed! Volume of box1 is 24 Volume of box2 is 1 Destructor of Box(1,1,1) is called! Destructor of Box(4,2,3) is called!,6.3.3 构造函数和析构函数调用次序,#include class Box private:float length,width,height;public:Box() length = 1; width
19、= 1; height = 1 cout“Box (1,1,1) is constructed!”endl;Box(float L,float w,float h)length =L; width = w; height = h; cout“Box(”L“,”w“,”“h”“) is constructed!”endl; Box()cout“Destructor of Box is called!“endl;float volume() return length * width * height; ;,6.3.4 成员函数,不属于任何类的函数称为普通函数; 成员函数隶属于某个类; 成员函数与
20、普通函数的区别 成员函数是属于某个类的,是类的一个成员 成员函数可以指定访问属性 成员函数可以访问本类的任何成员,而普通函数只能访问对象的公用成员 对于成员函数,一般是将需要被类外调用的声明为公用的,不需要被类外调用的声明为私有的。,【例6-6】 将例6-1中Student类的成员函数改为在类外定义的形式。,6.3.4 成员函数,class Student /声明Student类类型 public: /以下部分为公用成员函数void Show(); private: /以下部分是私有数据成员int stuNo;char stuName20;char stuSex; ; /类声明结束 /在类的声
21、明之外定义成员函数 void Student:Show() cout“No. :“stuNoendl;cout“Name:“stuNameendl;cout“Sex :“stuSexendl; ,(1)成员函数在类内定义或是在类外定义,对程序执行的效果基本一样。 (2)在类外定义成员函数时,必须首先在类内写出成员函数的原型,然后再在类外定义。 (3)如果在类外有函数定义,但是在函数名前没有类名和作用域运算符进行限定,则该函数被认为是普通函数。 (4)如成员函数的函数体很短,也可以将其定义在类内。 (5)在类内声明成员函数,在类外定义成员函数,是软件工程中要求的良好的编程风格。,注意,6.3.4
22、 成员函数,inline函数 在编译时将被调用函数的代码直接嵌入到调用函数处 inline成员函数就是将类中的成员函数声明为内置的 当类中的成员函数是在类内定义时,默认该成员函数是inline成员函数 如果成员函数定义在类的外部,则在成员函数声明或定义前必须要有inline关键字。,6.3.4 成员函数,6.4 类成员,class CTest public:int n;int getn( )return n; ;,问:若要打印数据成员类CTest中的n,如何写代码?,答:CTest test1;CTest *ptest2=new CTest;/couttest1.nn;coutptest2nn
23、; 类的成员函数内部引用该类的数据成员:int CTest:getn( ) return n; 没有指明类的具体实例,编译器如何决定引用哪一个实例对象的n拷贝呢?,6.4 类成员,int CTest:getn( ) return thisn; 编译器给成员函数传递一个隐藏的对象指针。 此指针指向函数调用所要引用的对象。 格式: X * const this; 类X的每一个成员函数中都隐式地声明了this指针。 小结:在类中,直接访问;在类外,利用对象访问。,6.4.1 this 指针,源程序,编译后,调用时,float Box:Volume() return length * width *
24、height; ,float Box:Volume(Box *this) return this-length * this-width * this-height; ,box1.Volume(,6.4.1 this 指针,成员对象:类的数据成员是另一个类的对象。 即一个类的对象中嵌套另一个类的对象。 例:P110上 在创建类对象时,也要创建成员对象;当用构造函数初始化嵌套对象时,也要用成员对象的构造函数初始化成员对象。 如果成员对象的构造函数带有参数,需要通过成员初始化符表把参数传到成员对象的构造函数中。 可以利用成员初始化符表初始化类中的常量和引用,而不能用赋值方式初始化他们。P110末,
25、6.4.2 成员对象和成员对象指针,成员对象指针:类的数据成员是一指向类对象的指针。 此指针可以指向当前类的对象。 例:P111 此指针的初始化在构造函数中完成,不必使用成员初始化符表。,6.4.2 成员对象和成员对象指针,在C+中,声明了一个类之后,可以定义该类的多个对象(实例)。 系统为每个对象分配单独的内存空间。每一个对象都分别有自己的数据成员,不同对象的数据成员各自有其值,互不相干。 但是有时我们希望有某一个或几个数据成员为所有对象所共有。这样可以实现数据共享。,6.4.3 静态类成员,6.4.3 静态类成员,我们知道全局变量能够实现数据共享。但是用全局变量的安全性得不到保证,因为在各
26、处都可以自由地修改全局变量的值,很有可能由于某个没注意到的失误,全局变量的值就被修改,导致程序的失败。因此在实际工作中很少使用全局变量。 如果想在同类的多个对象之间实现数据共享,也不要用全局对象,可以用静态成员。 静态成员包括静态数据成员和静态成员函数。,class CTest public:static int count;/ ;,6.4.3 静态类成员,例:,静态数据成员: 静态数据成员是一种特殊的数据成员。它以关键字static开头。 全局变量和该类的正常数据成员的综合。 由于它在类中声明,其作用域仅限于此类,访问受控。 在类外定义和初始化:int CTest:count=0;,静态数据
27、成员在内存中只占一份空间(而不是每个对象都分别为它保留一份空间),它是属于类的,但它被该类的所有对象所共享,每个对象都可以访问这个静态数据成员。 它独立于任何类对象存在,直接用类名和作用域分辨符访问它,无需引用对象来访问。 静态数据成员的值对所有对象都是一样的。如果改变它的值,则在各对象中这个数据成员的值都同时改变了。这样可以节约空间,提高效率。,6.4.3.1 静态数据成员,说明1: 如果只声明了类而未定义对象,则类的一般数据成员是不占内存空间的,只有在定义对象时,才为对象的数据成员分配空间。 但是静态数据成员不属于某一个对象,在为对象所分配的空间中不包括静态数据成员所占的空间。静态数据成员
28、是在所有对象之外单独开辟空间。 只要在类中定义了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被访问。在一个类中可以有一个或多个静态数据成员,所有的对象共享这些静态数据成员,都可以访问它。,6.4.3.1 静态数据成员,说明2: 静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放(一般数据成员是在对象建立时分配空间,在对象撤销时释放)。 静态数据成员是在程序编译时被分配空间的,到程序结束时才释放空间。,6.4.3.1 静态数据成员,说明3: 静态数据成员可以初始化,但只能在类体外进行初始化。如:int CTest:count=0; 静态数据成员初始化语句的一般形式为:
29、数据类型 类名:静态数据成员名=初值; 不必在初始化语句中加static。,6.4.3.1 静态数据成员,说明4: 静态数据成员既可以通过对象名访问,也可以通过类名来访问。,6.4.3.1 静态数据成员,【例6-7】 访问静态数据成员。,#include #include class Student public:Student(char *name=“no name“);Student();static int stu_count; char name40; ;,6.4.3.1 静态数据成员,Student:Student (char *pname) strcpy(name ,pname);
30、stu_count+; /每创建一个对象,学生人数加1 Student:Student () stu_count-; /每释放一个对象,学生人数减1 /对静态数据成员stu_count初始化 int Student:stu_count=0;,6.4.3.1 静态数据成员,int main() Student s1;couts1.stu_countendl; Student s2;couts2. stu_count endl; coutStudent:stu_count endl; return 0; ,程序运行结果如下: 1 2 1,6.4.3.1 静态数据成员,与静态数据成员不同,静态成员函
31、数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员。,6.4.3.2 静态成员函数,【例6-8】 静态成员函数访问静态数据成员的例子。,#include #include class Student /声明Student类 public:Student(char *name=“no name“);Student();static int getcount() return stu_count; private:static int stu_count; char name40; ;,6.4.3.2 静态成员函数,Student:Student (char *pname) strcpy(
32、name ,pname);stu_count+; /每创建一个对象,学生人数加1 Student:Student () stu_count-; /每销毁一个对象,学生人数减1 int Student:stu_count=0;,6.4.3.2 静态成员函数,int main() Student s1;couts1.getcount()endl; Student s2;couts2.getcount()endl;coutStudent:getcount()endl; return 0; ,6.4.3.2 静态成员函数,和静态数据成员一样,静态成员函数是类的一部分,而不是对象的一部分。如果要在类外调
33、用公用的静态成员函数,可以用类名和域运算符“:”,也允许通过对象名调用静态成员函数。如: Student:getcount(); /用类名调用静态成员函数 s1.getcount(); /用对象名调用静态成员函数 但这并不意味着此函数是属于对象s1的,而只是用s1的类型而已。,6.4.3.2 静态成员函数,说明1: 静态成员函数不能默认访问本类中的非静态成员。 当调用一个对象的成员函数(非静态成员函数)时,系统会把该对象的起始地址赋给成员函数的this指针。而静态成员函数并不属于某一对象,它与任何对象都无关,因此静态成员函数没有this指针。既然它没有指向某一对象,就无法对一个对象中的非静态成
34、员进行默认访问(即在访问数据成员时不指定对象名)。 可以说,静态成员函数与非静态成员函数的根本区别是:非静态成员函数有this指针,而静态成员函数没有this指针,因而决定了静态成员函数不能默认访问本类中的非静态成员。,6.4.3.2 静态成员函数,说明2: 静态成员函数可以直接访问本类中的静态数据成员,因为静态成员同样是属于类的,可以直接访问。 在C+程序中,静态成员函数主要用来访问静态数据成员,而不访问非静态成员。假如在一个静态成员函数中有以下语句: coutageendl; /若age已声明为static,则访问本类中的 /静态成员,合法coutscoreendl; /若score是非静
35、态数据成员,不合法,6.4.3.2 静态成员函数,但是,并不是绝对不能访问本类中的非静态成员,只是不能进行默认访问,因为无法知道应该去找哪个对象。如果一定要访问本类的非静态成员,应该加对象名和成员运算符“.”。如静态成员函数中可以出现:couts.scoreendl; 这里假设s已定义为Student类对象,且在当前作用域内有效,则此语句合法。 在C+程序中最好养成这样的习惯: 只用静态成员函数访问静态数据成员,而不访问非静态数据成员。这样思路清晰,逻辑清楚,不易出错。,6.4.3.2 静态成员函数,class conprivate: int i;const int c1; public:co
36、nst int c2; con(int i1,int i2): c1(i1),c2(i2) c1=1; /False!i=c1; ;,6.4.4 常量类成员,例1:,?void some_fun() con c(1,10); int i=c.c2;c.c2=I;i=c.c1;,常量数据成员作为私有数据时,只有内部函数可以读它;作为公有数据时,内外函数都可以读它。,class Xint m;public:int readme( ) const return m; void writeme (int i) m=i; ;,6.4.4 常量类成员,例2:,?int X:readme( ) const
37、int i;i=m;m+;return m;,常量成员函数可以修改局部变量、全局变量和其他类对象的值,但不能修改本类成员的值。,6.4.4 常量类成员,例3: 常量对象的数据成员不能被改变,因此常量对象只能调用常量成员函数。,?void f(X,(1)在一个类中可以根据需要将部分数据成员声明为常数据成员,另一部分数据成员为非const数据成员 (2)如果一个类的所有数据成员都不允许修改,可以将这个类中的所有数据成员都声明成const数据成员,或者定义对象时声明为const对象。 (3) const对象中的数据成员都是const数据成员,但是const对象中的成员函数不一定都是const成员函数
38、 (4)如果是const对象,只能调用其中的const成员函数 (5)在类的定义中,常成员函数不能调用非常成员函数,注意,6.4.4 常量类成员,6.5 友员、嵌套类和结构,友员可以访问与其有好友关系的类中的任何成员。 友员破坏了封装。,友员,友员函数,友员类,如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的普通函数,也可以是其他类的成员函数),在类体中用friend对其进行声明,此函数就称为本类的友员函数。友员函数可以访问这个类中的任何成员。 如何将普通函数声明为友元函数呢?看下面这个简单的例子:,6.5.1 友员函数,【例6-9】友元普通函数。,#include cla
39、ss Clock /声明Clock类public:Clock(int,int,int);friend void display(Clock ,6.5.1 友员函数,Clock:Clock(int h,int m,int s) /构造函数 hour=h; minute=m; second=s; void display(Clock ,6.5.1 友员函数,程序运行结果如下: 10:13:56,这是友员函数,形参t是Clock类对象的引用,【例6-10】友元成员函数。,#include class Date; class Clock /声明Clock类 public:Clock(int,int,i
40、nt);void display(Date ,Clock类的成员函数,对Date类的提前引用声明,6.5.1 友员函数,class Date /声明Date类 public:Date(int,int,int); friend void Clock:display(Date ,Date类的友元函数,6.5.1 友员函数,Clock:Clock(int h,int m,int s) / Clock类的构造函数 hour=h; minute=m; second=s; void Clock:display(Date ,6.5.1 友员函数,int main() Clock t(10,13,56); /
41、定义Clock类对象tDate d(12,25,2004); /定义Date类对象d/调用t的display函数,实参是Date类对象dt.display(d);return 0; ,程序运行结果如下: 12/25/2004 10:13:56,6.5.1 友员函数,不仅可以将一个函数声明为一个类的“朋友”,而且可以将一个类(例如B类)声明为另一个类(例如A类)的“朋友”。这时B类就是A类的友元类。 友元类B中的所有成员函数都是A类的友元函数,可以访问A类中的任何成员。,6.5.2 友员类,class Student; class Teacher public:void assigngrades
42、(Student,class Student public:friend Teacher; /友员类 protected:int num;string name;float score; ; ,声明友员类的一般形式为:friend 类名;,6.5.2 友员类,友员函数的声明可以出现在类的任何地方(包括在private和public部分),也就是说友员的说明不受成员访问控制符的限制。 友员关系是单向的而不是双向的,如果声明了B类是A类的友元类,不等于A类是B类的友元类,A类中的成员函数不一定能够访问B类中的成员 友员关系是不能传递的,例如,如果B类是A类的友元类,C类是B类的友元类,并不能说C类
43、就是A类的友元类。,6.5.2 友员类,说明,6.6 对象、指针和数组,6.6.1 对象数组 对象数组和普通的数组没有本质的区别,只不过普通的数组的元素是简单变量,而对象数组的元素是对象而已; 对象数组在实际中主要用于系统需要一个类的多个对象的情况; 在建立数组时,系统会自动调用每一个对象元素的构造函数。,【例6-11】创建含有3个长方体元素的长方体数组,并显示长方体构造函数的调用情况。,6.6.1 对象数组,#include using namespace std; class Box public:Box()Box(float L,float w,float h)Box()float Vo
44、lume() return length * width * height; private: float length,width,height; ;,int main() Box boxs3; /创建含有三个元素的对象数组boxsreturn 0; ,6.6.1 对象数组,int main() Box boxs3; /创建含有三个元素的对象数组boxsreturn 0; ,程序执行后运行的结果如下: Box (1,1,1) is constructed! Box (1,1,1) is constructed! Box (1,1,1) is constructed! Destructor o
45、f Box(1,1,1) is called! Destructor of Box(1,1,1) is called! Destructor of Box(1,1,1) is called!,6.6.1 对象数组,对象数组在建立时还可以给出实参以实现对数组元素进行不同的初始化 类有只有一个参数的构造函数,可以使用如下形式的数组初始化形式:ant colony_members3 = ant1,ant2,ant3; 如果对象的构造函数需要多个参数,则在初始化的花括号里要分别写明构造函数,并指定实参. 对象数组初始化举例:,6.6.1 对象数组,【例6-12】定义对象数组并初始化,观察对象数组建立的
46、情况。,6.6.1 对象数组,#include using namespace std; class Box public:Box()Box(float L,float w,float h)Box()float Volume() return length * width * height; private: float length,width,height; ;,int main() Box boxs3=Box(1,3,5),Box(2,4,6),Box(3,6,9); /创建含有三个元素的对象数组boxsreturn 0; ,6.6.1 对象数组,int main() Box boxs3
47、=Box(1,3,5),Box(2,4,6),Box(3,6,9); /创建含有三个元素的对象数组boxsreturn 0; ,程序执行后运行的结果如下: Box (1,3,5) is constructed! Box (2,4,6) is constructed! Box (3,6,9) is constructed! Destructor of Box(3,6,9) is called! Destructor of Box(2,4,6) is called! Destructor of Box(1,3,5) is called!,6.6.1 对象数组,int main() Box boxs3=Box(1,3,5),Box(),Box(3,6,9); /创建含有三个元素的对象数组boxsreturn 0; ,程序执行后运行的结果如下: Box (1,3,5) is constructed! Box (1,1,1) is constructed! Box (3,6,9) is constructed! Destructor of Box(3,6,9) is called! Destructor of Box(1,1,1) is called! Destructor of Box(1,3,5) is called!,