[计算机软件及应用]C++面向对象程序设计.ppt_第1页
[计算机软件及应用]C++面向对象程序设计.ppt_第2页
[计算机软件及应用]C++面向对象程序设计.ppt_第3页
[计算机软件及应用]C++面向对象程序设计.ppt_第4页
[计算机软件及应用]C++面向对象程序设计.ppt_第5页
已阅读5页,还剩103页未读 继续免费阅读

下载本文档

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

文档简介

,第3章 类和对象 3.1 类的构成 3.2 成员函数的定义 3.3 对象的定义和使用 3.4 构造函数与析构函数 3.5 对象的赋值与复制 3.6 自引用指针this 3.7 C+的string类,本章主要内容,3.1 类的构成 3.1.1 从结构体到类 3.1.2 类的构成,本节主要内容,3.1.1 从结构体到类 1.结构体的扩充 例如下面声明了一个日期结构体: struct Date int year; /年 int month; /月 int day; /日 ;,C语言结构体一般格式如下: struct 结构名 数据 ;,例3.1 有关日期结构体的例子。 #include using namespace std; struct Date /声明了一个名为Date的结构体 int year; int month; int day; ; int main() Date date1; date1.year=2010 ;/可以在结构体外直接访问数据year date1.month=8; /可以在结构体外直接访问数据month date1.day=25; /可以在结构体外直接访问数据day coutdate1.year“.“date1.month“.“ date1.dayendl; return 0; ,程序的运行结果如下: 2010.8.25,C语言中的结构体缺点:结构体变量可以在结构体外直接访问数据,在C结构体中的数据是很不安全的。,C+中引入了类的概念,克服了C结构体的缺点。,C+中引入了类的概念, 它不仅可以含有数据,而且还可以含有函数。 类中的数据和函数,分别称作数据成员和成员函数。,类声明的简化格式如下: class 类名 数据 函数 ;,类的声明由关键字class打头,后跟类名,花括号中是类体,以一个分号“;”结束,类声明的简化格式如下: class 类名 数据成员 函数函数 ;,3.1.2 类的构成 在类中,数据成员和成员函数分别属于private部分、和public部分。数据成员和成员函数一般也统称为类的成员。 类声明的一般格式如下:,class 类名 public: 公有数据成员; 公有成员函数; private: 私有数据成员; 私有成员函数; ;,公有成员既可被类内的成员函数访问,也可被类的外部访问,是类与外界的接口。,私有成员只能被类内的成员函数访问,而类外部的任何访问都是非法的。,用一个类Date来描述日期,其形式如下: class Date public: void setDate(int y,int m,int d); /公有成员函数 void showDate(); /公有成员函数 private: int year; /私有数据成员 int month; /私有数据成员 int day; /私有数据成员 ;,私有数据成员year、month和day只能由内部成员函数访问,在类的外部无法访问, 保护了私有数据的安全。,设置日期成员函数setDate和日期显示成员函数showDate都是公有的成员函数,类外部对类Date的数据进行操作,只能通过这两个函数来实现。,说明: (1) 除了private和public之外,类中的成员还可以用另一个关键字 protected来说明。被protected说明的数据成员和成员函数称为保护成员。 类声明的完整格式如下:,class 类名 public: 公有数据成员; 公有成员函数; protected: 保护数据成员; 保护成员函数; private: 私有数据成员; 私有成员函数; ;,保护成员可以由本类的成员函数访问,也可以由本类的派生类的成员函数访问,而类外的任何访问都是非法的,将在第5章详细介绍。,(2) 对一个具体的类来讲,类声明格式中的3个部分并非一定要全有,但至少要有其中的一个部分。 一般情况下,一个类的数据成员应该声明为私有成员,成员函数声明为公有成员。 这样,内部的数据整个隐蔽在类中,在类的外部根本就无法看到,使数据得到有效的保护。 (3) 类声明中的private、protected和public三个关键字可以按任意顺序出现任意次。但是,如果把所有的私有成员、保护成员和公有成员归类放在一起,程序将更加清晰。 (4) C+规定,在默认情况下(即没有指定成员是私有、保护或公有时),类中的成员是私有的。,例3.2 将例3.1中的结构体struct改为类class。 #include using namespace std; class Date /将例3.1中的结构体struct改为类class int year; /私有数据成员 int month; /私有数据成员 int day; /私有数据成员 ; int main() Date date1; date1.year=2010;/错误,在类外不能访问私有数据成员year date1.month=8; /错误,在类外不能访问私有数据成员month date1.day=25; /错误,在类外不能访问私有数据成员day coutdate1.year“.“date1.month“.“ date1.dayendl; /错误,不能访问私有数据成员 return 0; ,私有成员只能被类内的成员函数访问,而类外部的任何访问都是非法的。,如何才能访问类中的私有数据成员呢?将在3.2节作详细的介绍。,#include /例3.1 有关日期结构体的例子。 using namespace std; struct Date /声明了一个名为Date的结构体 int year; /公有的数据成员 int month; /公有的数据成员 int day; ; /公有的数据成员 int main() Date date1; date1.year=2010 ; /可以在结构体外直接访问数据year date1.month=8; /可以在结构体外直接访问数据month date1.day=25; /可以在结构体外直接访问数据day coutdate1.year“.“date1.month“.“ date1.dayendl; return 0; ,程序的运行结果如下: 2010.8.25,在默认情况下,结构体中的成员是公有的。因此,例3.1中数据成员year、month和day默认为是公有的,结构体外的变量date1能够对它们直接进行访问,(5)不能在类声明中给数据成员赋初值。 例如: class abc private: char a=q; /错误 int b=33; /错误 public: ; C+规定,只有在对象定义之后才能给数据成员赋初值,3.2 成员函数的定义 3.2.1 普通成员函数的定义 3.2.2 内联成员函数的定义,本节主要内容,3.2.1 普通成员函数的定义 将成员函数以普通成员函数(即非内联的成员函数)的形式进行定义。 在类声明中只给出成员函数的原型, 而将成员函数的定义放在类外部。 例如: Student成员函数名(参数表),成员函数在类外定义的一般形式是: 返回值类型 类名成员函数名(参数表) 函数体 ,在类名和成员函数名之间应加上作用域运算符“”,class Student /学生类的定义-1 private: int number; float score; public: void input(int number1,float score1);/函数原型1,输入成绩 void modify(float score1); /函数原型2,修改成绩 void print(); /函数原型3,打印成绩 ; void Student:input(int number1,float score1)/函数定义1 number=number1; score=score1; void Student:modify(float score1) /函数定义2 score=score1; void Student:print() /函数定义3 cout“nnumber:“number “ score:“score;,在类声明中只给出成员函数的原型,而将成员函数的定义放在类外部。,在函数名前应加上类名和作用域运算符“”,说明: (1) 在类声明中,成员函数原型的参数表中可以不说明参数的名字,而只说明它们的类型。例如: void modify(float score1); 但是,在类外定义成员函数时,不但要说明参数表中参数的类型,还必须要指出其参数名。例如: void Student:modify(float score1) score=score1; (2) 采用“在类声明中只给出成员函数的原型,而将成员函数的定义放在类的外部”的定义方式,是C+程序设计的良好习惯。,3.2.2 内联成员函数的定义 (1) 隐式声明 将成员函数直接定义在类的内部。 例如: class Student /学生类的定义-2 private: int number; float score; public: void input(int number1,float score1)/定义成员函数 number=number1; score=score1; void modify(float score1) /定义成员函数 score=score1; void print() /定义成员函数 cout“nnumber:“number “score: “score; ;,将成员函数直接定义在类内部,编译时是作为内联函数的方式来处理(内联函数隐式定义),(2)显式声明 在类声明中只给出成员函数的原型,而成员函数的定义放在类外部。但在类外部成员函数的定义前冠以关键字“inline”,使它起到内联函数的作用。 class Student private: int number; float score; public: void input(int number1,float score1); . . . ; inline void Student:input(int number1,float score1) number=number1; score=score1;,成员函数的原型,冠以关键字“inline”,使用 inline定义内联函数时,可以在声明函数原型和定义函数时同时写inline,也可以在其中一处声明inline,效果是相同的,都能按内联函数处理。 但是,必须将类的声明和内联成员函数的定义都放在同一个文件(或同一个头文件)中,否则编译时无法进行代码置换。,class Student /学生类的定义-3 private: int number; float score; public: inline void input(int number1,float score1);/函数原型1 inline void modify(float score1); /函数原型2 inline void print(); /函数原型3 ; inline void Student:input(int number1,float score1) number=number1; /函数定义1 score=score1; inline void Student:modify(float score1) score=score1; /函数定义2 inline void Student:print() /函数定义3 cout“nnumber:“number “ score:“score;,冠以关键字“inline”,3.3 对象的定义和使用 3.3.1 类与对象的关系 3.3.2. 对象的定义 3.3.3 对象中成员的访问 3.3.4 类的作用域和类成员的访问属性,本节主要内容,3.3.1 类与对象的关系 在C+中,类与对象间的关系,可以用数据类型int和整型变量i之间的关系来类比。类类型和int类型均代表的是一般的概念,而对象和整型变量却是代表具体的东西。,3.3.2. 对象的定义 定义对象可以用以下两种方法: 方法 1: 在声明类的同时,直接定义对象,即在声明类的右花括号“ ”后,直接写出属于该类的对象名表。 例如: class Student / stu1,stu2;,在声明类Student 的同时,直接定义对象stu1和stu2,方法 2: 声明了类之后,在使用时再定义对象。其一般形式如下: class Student / ; Student stu1, stu2;,在使用时再定义对象,此时定义了类Student的两个对象stu1和stu2,说明: 声明了一个类便声明了一种类型,这时没有给它分配存储空间,只有定义了对象后,系统才为对象分配存储空间。,类名 对象名1,对象名2,;,3.3.3 对象中成员的访问 不论是数据成员,还是成员函数,只要是公有的,在类的外部可以通过类的对象进行访问。访问对象中的成员通常有以下三种方法。 (1) 通过对象名和对象选择符访问对象中的成员 其一般形式是: 其中“”叫做对象选择符,简称点运算符。,对象名数据成员名 或 对象名成员函数名(实参表),#include /学生类的完整程序 using namespace std; class Student private: int number; float score; public: void input(int number1,float score1); /输入学生成绩 void modify(float score1); /修改学生成绩 void print(); /打印学生成绩 ; void Student:input(int number1,float score1) number=number1; score=score1; void Student:modify(float score1) score=score1; void Student:print( ) cout“nnumber:“number“score:“score;,int main( ) Student stu1,stu2; stu1.input(9901,95); stu2.input(9902,75); stu1.print(); stu2.print(); stu1.modify(85.5); stu1.print(); stu2.print(); return 0; ,stu1.number=9901, stu1.score=95 stu2.number=9902, stu2.score=75,stu1.score=85.5,运行结果: number: 9901 score:95 number: 9902 score:75 number: 9901 score:85.5 number: 9902 score:75,#include/例3.3-1通过对象名和对象选择符访问对象中的成员。 using namespace std; class Date public: void setDate(int y,int m,int d); void showDate(); private: int year; int month; int day; ; void Date:setDate(int y,int m,int d) year=y; month=m; day=d; void Date:showDate()coutyear“.“month“.“dayendl; int main() Date date1; cout“Date1 set and output:“endl; date1.setDate(2010,4,28); date1.showDate(); return 0; ,调用对象date1的公有成员函数setDate,给date1的私有数据成员赋值,调用对象date1公有成员函数showDate, 显示date1的私有数据成员,程序运行结果如下: Date1 set and output: 2010.4.28,说明: 在类外只能访问公有(public)成员,而不能访问私有(private)成员。 如果将例3.3中的主程序改成下面的形式,将出现编译错误: int main() Date date1; date1.year=2010; date1.month=8; date1.day=25; coutdate1.year“.“date1.month“.“date1.dayendl; return 0; ,错误,在类的外部,对象date1不能访问私有数据成员year、month和day,(2)通过指向对象的指针访问对象中的成员 此时,访问此对象的成员时,不能用“.”操作符,而应使用“- ”操作符。 例如: class Date public: int year; ; Date d, *ptr; /定义对象d和指向类Date的指针变量ptr ptr= /输出ptr指向对象中的成员year,d.year (*ptr).year 三者是等价的 ptr-year,(3)通过对象的引用访问对象中的成员 如果为一个对象定义了一个引用,也就是为这个对象起了一个别名。 例如: class Date public: int year; . ; Date d1; /定义类Date的对象d1 Date /输出对象d2中的数据成员year,由于d2是d1的引用(即d2和d1占有相同的存储单元),因此d2.year和d1.year是相同的。,3.3.4 类的作用域和类成员的访问属性 所谓类的作用域就是指在类的声明中的一对花括号所形成的作用域。一个类的所有成员都在该类的作用域内。 在类的作用域内,一个类的任何成员函数成员可以不受限制地访问该类中的其他成员。 而在类作用域之外,对该类的数据成员和成员函数的访问则要受到一定的限制,有时甚至是不允许的。 这主要与类成员的访问属性有关。,类成员有二种访问属性:公有属性和私有属性。 说明为公有的成员不但可以被类中成员函数访问,还可在类的外部,通过类的对象进行访问。 说明为私有的成员只能被类中成员函数访问,不能在类的外部,通过类的对象进行访问。,换一种说法: 类内部的成员函数可以访问类的所有成员,没有任何限制, 类外部的对象可以访问类的公有成员,不能访问类的私有成员 。,class Sample private: int i; /私有成员 public: int j; /公有成员 void set(int i1,int j1) /公有成员 i=i1; /类的成员函数可以访问类的私有成员i j=j1; /类的成员函数可以访问类的公有成员j ; int main() Sample a;/定义类Sample的对象a a.set(3,5); couta.iendl; couta.jendl; return 0; ,非法,类Sample的对象a不能访问类的私有成员i,在类外,类Sample的对象a可以访问公有成员函数set(),合法,类Sample的对象a能够访问类的公有成员j,分析以下程序段,一般而言,公有成员是类的对外接口,而私有成员是类的内部数据和内部实现,不希望外界访问。,3.4 构造函数与析构函数 3.4.1 对象的初始化和构造函数 3.4.2 用成员初始化表对数据成员初始化 3.4.3 析构函数 3.4.4 默认的构造函数和默认的析构函数 3.4.5 带默认参数的构造函数 3.4.6 构造函数的重载,本节主要内容,3.4.1 对象的初始化和构造函数 与使用变量一样,对象时也应该“先定义,后使用”。在定义对象时,对数据成员赋初值,称为对象的初始化。 C+规定,类声明体中不能给数据成员直接赋初值, 下面的写法是错误的: class Date private: int year=2010; /错误 int month=6; /错误 int day=16; /错误 ;,对象的初始化常采用以下两种方法: 1. 调用普通的成员函数来完成 2. 调用构造函数来完成,class Date public: void setDate(int y,int m,int d); void showDate(); private: int year; int month; int day; ; int main() Date date1; date1.setDate(2010,4,28); return 0; ,调用对象date1的公有成员函数setDate,给date1的私有数据成员赋初值,初始化后: Date1.year=2010 Date1.month =4 Date1.day =28,1.用普通成员函数对对象进行初始化,在建立对象的时,采用构造函数给数据成员赋初值,通常有以下两种形式。 形式1: 类名 对象名(实参表); 这里的“类名”与构造函数名相同,“实参表”是为构造函数提供的实际参数。,2.用构造函数对对象进行初始化,构造函数是一种特殊的成员函数,它主要用于: (1) 为对象分配空间 (2) 为对象的数据成员进行初始化 (3) 其他指定的任务,#include/例3.5-1 using namespace std; class Date public: Date(int y,int m,int d); /声明构造函数Date的原型 void showDate(); private: int year; int month; int day; ; Date:Date(int y,int m,int d) /定义构造函数Date year=y; month=m; day=d; inline void Date:showDate() coutyear“.“month“.“dayendl; int main() Date date1(2010,4,28); date1.showDate(); return 0; ,(3) 定义类Date的对象date1,调用构造函数, 给对象date1的数据成员赋初值,(2) 构造函数可以有任意类型的参数,但不能具有返回类型,(1)构造函数的名字必须与类名相同,通常,利用构造函数建立对象有以下二种方法: (1) 一般形式为: 类名 对象名(实参表); 例如: complex A(1.1,2.2); 类名 对象名 实参表,在建立对象的时,采用构造函数对对象进行初始化,通常有以下两种形式: 形式1: 例如: Date date1(2010,4,28); 类名 对象名 实参表,建立对象时,编译系统会自动地调用构造函数,对对象进行初始化,类名 对象名(实参表);,形式2: 其一般语法形式为: 例如: Date *pdate = new Date(2010,4,28); 类名 *指针变量名=new 类名(实参表); 指针pdate指向该对象的地址 对象名: 匿名对象,或称对象名是(*pdate) 此时,应使用“-”来访问对象的成员,而不是“.” 。,类名 *指针变量名=new 类名(实参表);,将例3.5-1的主函数改成用这种方法来实现。 int main() Date *pdate = new Date(2010,4,28); pdate-showDate(); delete pdate; return 0; ,利用构造函数创建对象的另一种方法:用指针和new来实现。,说明: (1) 构造函数的名字必须与类名相同,否则编译程序将把它当作一般的成员函数来处理。 (2) 构造函数没有返回值,在声明和定义构造函数时,是不能说明它的类型的,甚至说明为void类型也不行。 例如上述构造函数不能写成 void Date(int y,int m,int d);,说明为void类型也不行,(3) 与普通的成员函数一样,构造函数的函数体可写在类体内,也可写在类体外。 如例3.5-1中的类Date可以声明如下: class Date public: Date(int y,int m,int d) / 构造函数定义在类内 year=y; month=m; day=d; void showDate() coutyear“.“month“.“dayendl; private: int year; int month; int day; ;,构造函数的函数体也可写在类体外,(4) 构造函数一般声明为公有成员,但它不需要也不能像其他成员函数那样被显式地调用,它是在定义对象的同时被自动调用的。 例如,下面的用法是错误的: date1.Date(2010,4,28);,(5) 构造函数可以是不带参数的。例如: class A private: int x; public: A( ) x=50; ; int main() A a; ,构造函数可以不带参数,定义类A的对象a时,调用不带参数的构造函数给数据成员x赋初值50,3.4.2 用成员初始化表对数据成员初始化,class A int i; float f; public: A(int i1,float f1) i=i1;f=f1; ;,class A int i; float f; public: A(int i1,floatf1 ):i(i1),f(f1) ;,在构造函数中一般用赋值语句对数据成员的初始化进行,C+还提供另一种初始化数据成员的方法-用成员初始化列表来实现对数据成员的初始化。,带有成员初始化列表的构造函数的一般形式如下: 成员初始化列表的一般形式为:,类名:构造函数名(参数表):(成员初始化列表) 构造函数体 ,数据成员名1(初始值1),数据成员名2(初始值2),#include /例3.6 using namespace std; class Date public: Date(int y,int m,int d); /声明构造函数的原型 void showDate(); private: int year; int month; int day; ; Date:Date(int y,int m,int d):year(y),month(m),day(d) void Date:showDate() coutyear“.“month“.“dayendl; int main() Date date1(2010,4,28); /定义类Date的对象date1 date1.showDate(); return 0; ,定义构造函数Date(),使用成员初始化表对数据成员初始化,运行结果如下: 2010.4.28,说明:数据成员是按照它们在类中声明的顺序进行初始化的,与它们在成员初始化列表中列出的顺序无关。 练习1 写出以下程序的运行结果。 #include using namespace std; class D int mem1; int mem2; public: D(int i):mem1(i),mem2(mem1+1) cout“mem1: “mem1endl; cout“mem2: “mem2endl; ; void main() D d(15); ,相当于: mem1=i; mem2=mem1+1,运行结果为: mem1: 15 mem2: 16,#include using namespace std; class D int mem1; int mem2; public: D(int i):mem2(i),mem1(mem2+1) cout“mem1: “mem1endl; cout“mem2:“mem2endl; ; void main() D d(15); ,相当于: mem2=i; mem1=mem2+1;,请问:运行结果?,mem1: 16 mem2: 15 实际运行结果: mem1: 858993459 mem2: 15,原因:不是按照构造初始化表的顺序对数据成员进行初始化,而是按照数据成员在类里被声明的顺序进行初始化,练习2,#include using namespace std; class D int mem1; int mem2; public: D(int i):mem2(i),mem1(mem2+1) cout“mem1: “mem1endl; cout“mem2:“mem2endl; ; void main() D d(15); ,初始化过程: 1.mem1=mem2+1=随机数 2.mem2=i=15,程序结果如下: mem1: -858993459 mem2: 15,解决方法?,练习2,分析错误原因,/练习2 #include using namespace std; class D int mem2; int mem1; public: D(int i):mem2(i),mem1(mem2+1) cout“mem1: “mem1endl; cout“mem2:“mem2endl; ; void main() D d(15); ,将mem1和 mem2交换,运行结果为: mem1: 16 mem2: 15,3.4.3 析构函数 析构函数也是一种特殊的成员函数。它执行与构造函数相反的操作,通常用于执行一些清理任务,主要有: 1. 释放分配给对象的内存空间。 2. 其他指定的任务,class Student /带构造函数的学生类 private: int number; float score; public: Student(int number1,float score1); Student( ) cout“destructing”; ; Student : Student(int number1,float score1) number=number1; score=score1; ,构造函数,析构函数,class Student private: int number; float score; public: Student(int number1,float score1); Student( ) cout“destructing”; ; Student : Student(int number1,float score1) number=number1; score=score1; ,析构函数与类名相同,但它前面必须加一个波浪号(),析构函数没有参数,也没有返回值,当撤消对象时,编译系统会自动地调用析构函数,析构函数有以下一些特点: (1) 析构函数名与类名相同,但它前面必须加一个波浪号()。 (2) 析构函数不返回任何值。在定义析构函数时,是不能说明它的类型的,甚至说明为void类型也不行。 (3) 析构函数没有参数,因此它不能被重载。一个类可以有多个构造函数,但是只能有一个析构函数。 (4) 撤销对象时,编译系统会自动地调用析构函数。,#include/例3.7含有构造函数和析构函数的Date类。 using namespace std; class Date public: Date(int y,int m,int d); / 声明构造函数 Date(); / 声明析构函数 void setDate(int y,int m,int d); void showDate(); private: int year; int month; int day; ; Date:Date(int y,int m,int d) / 定义构造函数 cout“constructing.“endl; year=y; month=m; day=d; Date:Date() / 定义析构函数 cout“destruting.“endl; void Date:setDate(int y,int m,int d) year=y; month=m; day=d; ,inline void Date:showDate() coutyear“.“month“.“dayendl; int main() Date date1(2010,4,28); date1.showDate return 0; ,程序运行结果如下: constructing. 2010 .4.28 destruting.,定义类Date的对象date1,调用date1的构造函数,初始化对象date1,说明: 在以下情况, 当对象的生命周期结束时,析构函数会被自动调用: 如果定义了一个全局对象,则在程序流程离开其作用域时(如main函数结束或调用exit函数)时,调用该全局对象的析构函数。 如果一个对象被定义在一个函数体内,则当这个函数结束时,该对象的析构函数被自动调用。 若一个对象是使用new运算符动态创建的,在使用delete运算符释放它时,delete会自动调用析构函数。,#include /例3.8 较完整的学生类示例。 #include using namespace std; class Student public: Student(char *name1,char *stu_no1,float score1); /声明构造函数 Student(); /声明析构函数 void disp(); /成员函数,用于显示数据 private: char *name; char *stu_no; float score; ; /姓名,学号,成绩 Student:Student(char *name1,char *stu_no1,float score1) name=new charstrlen(name1)+1; strcpy(name,name1); stu_no=new charstrlen(stu_no1)+1; strcpy(stu_no,stu_no1); score=score1; ,定义构造函数,Student:Student() /定义析构函数 delete name; delete stu_no; void Student:disp() cout“name: “nameendl; cout“stu_no: “stu_noendl; cout“score: “scoreendl; int main() Student stu1(“Li ming“,“20080201“,90); stu1.disp(); Student stu2(“Wang fun“,“20080202“,85); stu2.disp(); return 0; ,定义类Student的对象stu1,调用构造函数,初始化对象stu1,定义类Student的对象stu2,调用构造函数,初始化对象stu2,运行结果如下: name: Li ming stu_no: 20080201 score: 90 name: Wang fun stu_no: 20080202 score: 85,3.4.4 默认的构造函数和默认的析构函数 1. 默认的构造函数 如果没有在类中定义构造函数,则编译系统自动地生成一个默认的构造函数。 例如,编译系统为类Date生成下述形式的构造函数: DateDate( ) 这个默认的构造函数,不带任何参数,只能为对象开辟一个存储空间,而不能给对象中的数据成员赋初值。,例3.9 一个没有对数据成员赋初值的例子。 #include using namespace std; class Myclass public: int no; ; int main() Myclass a; couta.noendl; return 0; ,运行结果如下: -858993460,不难看出,本例的运行结果是一个随机数,在实际使用时可能会造成错误。,说明: (1) 对没有定义构造函数的类,其公有数据成员可以用初始值表进行初始化。请看以下例子: 例3.10 用初始值表初始化公有数据成员。 #include using namespace std; class Myclass public: char name10; int no; ; int main() Myclass a=“chen“,25; “ “a.noendl; return 0;,运行结果如下: chen 25,用初始值表初始化公有数据成员,(2) 只要一个类定义了构造函数(不一定是无参构造函数),系统将不再给它提供默认的构造函数。 #include class Location private: int X,Y; public: void Init(int initX, int initY) X=initX; Y=initY; int GetX( ) return X; int GetY( ) return Y; ; int main( ) Location A3; A3.Init(785,980); coutA3.GetX( )“ “A3.GetY( )endl; return 0;,类中没有用户定义的构造函数,C+编译系统自动地生成一个默认的构造函数,定义对象时,就调用这个自动生成的默认的构造函数,运行结果: 785 980,#include /例3.10 分析下列程序的运行结果。 using namespace std; class Date public: Date(int y,int m,int d); /带有参数的构造函数 void setDate(int y,int m,int d); void showDate(); private: int year; int month; int day; ; Date:Date(int y,int m,int d) year=y; month=m; day=d; void Date:setDate(int y,int m,int d) year=y; month=m; day=d; inline void Date:showDate() coutyear“.“month“.“dayendl; ,int main() Date date1; date1.setDate(2002,11,14); date1.showDate(); return 0; ,程序的运行结果是: 2002.11.14,错误的原因是,当类中定义了带有参数的构造函数后,系统将不再给它提供默认的构造函数。因此当定义类Date的对象date1时,找不到与之匹配的构造函数。,#include /例3.10 分析下列程序的运行结果。 using namespace std; class Date public: Date(int y,int m,int d); /带有参数的构造函数 void setDate(int y,int m,int d); void showDate(); private: int year; int month; int day; ; Date:Date(int y,int m,int d) year=y; month=m; day=d; void Date:setDate(int y,int m,int d) year=y; month=m; day=d; inline void Date:showDate() coutyear“.“month“.“dayendl; ,int main() Date date1; / date1.setDate(2002,11,14); / date1.showDate(); return 0; ,方法1:把语句 改为 Date date1(2002,11,14);,解决方法?,方法2: 增加一个如下的构造函数 Date( ) ,2.默认的析构函数 每个类必须有一个析构函数。若没有显式地为一个类定义析构函数,编译系统会自动地生成一个缺省的析构函数。 例如: DateDate() ,当撤消对象时,这个缺省的析构函数将释放分配给对象的内存空间。,说明: 对于大多数类而言,默认的析构函数就能满足要求。但是,如果在一个对象完成其操作之前需要做一些内部处理,则应该显式地定义析构函数,以完成所需的操作。 如例3.8中的析构函数: Student:Student() delete name; /释放由运算符new分配的内存空间 delete stu_no; /释放由运算符new分配的内存空间 ,3.4.5 带默认参数的构造函数 在实际使用中,有些构造函数的参数值在大部分情况是相同的,只有在特殊情况下才需要改变它的参数值。 例如 大学本科的学制一般默认为4年, 某大学工科的学费一般默认为每年5000元, 计时器的初始值一般默认为0等。 这时可以将其定

温馨提示

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

评论

0/150

提交评论