第5章类和对象(一)

来源:互联网 发布:由 诲女知之乎 编辑:程序博客网 时间:2024/06/06 03:10
第5章类和对象(一)(2008-06-09 08:41:04)转载标签:构造函数daydate数据类型it分类:c++学习相关第5章类和对象5.1 结构C++具有丰富的基本数据类型,如:char、int、double等等,使用这些数据类型,已经可以解决很多问题了。但是,在某些场合,数据类型的集合可以更方便地解决某些问题。例如:数组,它把若干相同类型的数据集合在一起,解决了成批同类型数据的处理问题。对于由 “若干相同类型的数据集合”构成的数组,由于每个元素的类型都相同,因此,其数组的“整体类型”也就是这个公共的类型了。所以,其处理过程也比较简单,数组中的每一个元素等价于同类型的一个变量,使用下标方法就可以方便地处理数组元素。在实际问题中,我们往往会碰到“一组数据中的各个数据具有不同类型”的情况。例如,例如,对于处理一个班的学生成绩问题时,每个人都涉及到“姓名、性别、年龄、成绩”的问题,这一组组的数据都有内在联系且类型不同,姓名应为字符型数组,性别应为字符型;年龄应为整型;成绩可为整型或实型。显然不能用一个数组来存放这一组数据。对于这样的由“若干不同类型的数据集合”而构成的整体,C++称之为结构。结构中,各成员的类型不一定相同,那么该如何表达其“整体类型”呢?C++提供了一种自定义数据类型的机制,即允许程序员自己创造数据类型。这种可以自定义数据类型的方法,可以为我们解决复杂问题提供了方便。C++内部数据类型的名称全是由小写字母构成的,为了与之区别,我们一般将自定义数据类型的名称以大写字母开头。一、结构类型的定义定义某个特定结构类型,采用以下一般形式:struct 结构名{类型说明符 成员名1;类型说明符 成员名2;类型说明符 成员名3;类型说明符 成员名4;……      ……};   例如:struct Stu{char name[20];char sex;int age;float score;};注意:在括号后的分号是不可少的。结构类型定义好之后,即可用这个类型去进行变量说明。这时,被说明的变量,是由数目固定的有序变量的集合,结构中的每一个变量的类型可能是不相同的。由此可见,结构是一种复杂的数据类型。 二、结构类型变量的说明说明结构变量有以下三种方法。以上面定义的stu为例来加以说明。1)先定义结构,再说明结构变量。这是最常用的方法,如:struct Stu{char name[20];char sex;int age;float score;};Stu boy1,boy2;说明了两个变量boy1和boy2为stu结构类型。 2)在定义结构类型的同时说明结构变量。例如:struct Stu{char name[20];char sex;int age;float score;}boy1,boy2; 3)直接说明结构变量。例如:struct{char name[20];char sex;int age;float score;}boy1,boy2; 成员也可以又是一个结构,即构成了嵌套的结构。例如:struct Date{int month;int day;int year;};Struct{char name[20];char sex;Date birthday;double score;}boy1,boy2; 三、结构变量中成员名的使用1、成员名可与程序中其它变量同名,互不干扰。2、表示结构变量成员的一般形式是:结构变量名.成员名例如:boy1.num 即第一个人的学号 boy2.sex即第二个人的性别。3、如果成员本身又是一个结构则必须逐级找到最低级的成员才能使用。例如:boy1.birthday.month 即第一个人出生的月份4、给结构变量的赋值就是给各成员赋值。可用输入语句或赋值语句来完成。例题:日期结构#include<iostream.h> struct Date{int year;int month;int day;}; void print(Date);bool isLeapYear(Date d); void main(){Date d;d.year = 2000;d.month = 12;d.day = 6;if(isLeapYear(d))  print(d);} void print(Date s){ cout<<s.year<<'-'<<s.month<<'-'<<s.day<<endl;} bool isLeapYear(Date d){return(d.year%4==0&&d.year%100!=0)||(d.year%400==0);}结构类型的定义还是存在局限性,它只定义了一组不同类型数据的集合,而没有定义相关操作,如赋值、输出等。特别是在一个程序员接手另一个程序员工作的时候,这种对结构的理解和编写相关操作的负担加重了。为了减轻其它程序员的编程负担,我们需要把结构类型的定义做得更全面些,使它不仅仅有数据的定义,而且有操作的定义,这就是类。 5.2 类与对象一、什么是类类是一种由程序员自己创造的复杂数据类型。具体说:类是一个数据类型;类类型通常很复杂;类类型是由程序员自己创造的。程序员将各种彼此相关的各种类型的数据和与这些数据相关的操作(函数)封装在一起的,便创造了一个具体类类型。通俗地说,类类型中包含了若干数据,还包含了若干函数。二、类类型的定义采用C++提供的自定义数据类型的机制,由程序员自己创造数据类型的方法,完成类类型的定义。类类型的定义一般又两部分构成:说明部分和实现部分。说明部分是用来说明该类中的成员,包含数据成员的说明和成员函数的说明。成员函数是用来对数据成员进行操作的,又称为“方法”。实现部分是用来对成员函数的定义。概括说来,说明部分将告诉使用者“干什么”,而实现部分是告诉使用者“怎么干”。1、类的一般定义格式如下:class 类名{   public:       数据成员或成员函数的说明   private:       数据成员或成员函数的说明   protected       数据成员或成员函数的说明};各个成员函数的实现 2、定义类时应注意的事项A、class是定义类类型的关键字,“类名”是标识符,通常用大写字母开始的字符串作为类名。B、花括号内是类的说明部分,说明该类包含哪些数据成员和哪些成员函数。C、类中的数据成员的类型可以是任意的,包含整型、浮点型、字符型、数组、指针和引用等。D、另一个类的对象,可以作该类的成员。当一个类的对象为这个类的成员时,如果另一个类的定义在后,需要提前说明。E、在类体中不允许对所定义的数据成员进行初始化,因为类的定义只是在创造一个类型而已,而不是在说明“变量”。 3、类成员的访问控制A、从访问权限上来分,类的成员又分为:公有的(public)、私有的(private)和保护的(protected)三类。B、公有成员用public来说明,公有部分往往是一些操作(成员函数),它是提供给用户的接口。这部分成员可以在程序中引用。C、私有成员用private来说明,私有部分通常是一些数据成员,这些成员是用来描述该类中的对象的属性的,只有成员函数或经特殊说明的函数才可以引用它们,它们是被用来隐藏的部分。D、保护成员用protected来说明,在大多数情况下,类的保护成员具有私有成员的性质,但在派生类的成员函数而言,它具有公有成员的性质。关键字public、private和protected被称为访问权限修饰符或访问控制修饰符,用它们来说明类成员的访问权限。它们在类体内出现的先后顺序无关,并且允许多次出现。一般地,在类体内先说明公有成员,它们是用户所关心的,后说明私有成员,它们是用户不感兴趣的。在说明数据成员时,一般按数据成员的类型大小,由小至大说明,这样可提高时空利用率。经常习惯地将类定义的说明部分或者整个定义部分(包含实现部分)放到一个头文件中。4、类成员函数的实现在类类型的定义中,“各个成员函数的实现”是类定义中的实现部分,这部分包含所有在类体内说明的函数的定义。返回值的类型 类名::成员函数名(参数表){函数体}其中“::”叫作用域运算符。如果一个成员函数的类体内定义了,实现部分将不出现。如果所有的成员函数都在类体内定义,则实现部分可以省略。例题:日期类的定义(说明部分+实现部分)class Date{public:    void set(int y,int m,int d);// 赋值操作    boolisLeapYear();       // 判断闰年    voidprint();              // 输出日期private:    int year,month,day;}; void Date::set(int y,int m,int d){    year=y;    month=m;    day=d;} bool Date::isLeapYear(){    return(year%4==0&&year%100!=0)||(year%400==0);} void Date::print(){    cout<<year<<'-'<<month<<'-'<<day<<endl;} 三、对象回忆变量的定义方法:double x,y,z;1、类似于用基本数据类型来说明变量的方法,我们可以用自己创建的类类型来说明“变量”,此时的“变量”叫对象。2、访问对象的公有成员:当用自己创建的类类型来说明“对象”以后,程序中就可以用运算符“.”来引用其公有成员,引用的方式如下:对象名.公有数据成员名对象名.公有成员函数名(实参表)对“对象”中数据成员的赋值和数据传递一般都是通过成员函数来进行的。#include<iostream.h> class Date{public:    void set(int y,int m,int d);// 赋值操作    boolisLeapYear();       // 判断闰年    voidprint();              // 输出日期private:    int year,month,day;}; void Date::set(int y,int m,int d){    year=y;    month=m;    day=d;} bool Date::isLeapYear(){    return(year%4==0&& year%100!=0)||(year%400==0);} void Date::print(){    cout<<year<<'-'<<month<<'-'<<day<<endl;} void main(){    Date d;    d.set(2000,12,6);    if(d.isLeapYear())        d.print();} 指向对象的指针的成员表示如下:对象指针名->公有数据成员名对象指针名->公有成员函数名(实参表)  注意:->用于表示指向对象的指针的成员       . 用于表示一般对象的成员下列表示是等价的:对象指针名->公有数据成员名(*对象指针名).公有数据成员名 5.3 对象的初始化一、构造函数和析构函数1、什么是构造函数在进行类的定义时(程序员自己创建类类型),不能给类中数据进行初始化,因为在这一过程中,仅仅是创建一个类类型而已。就好象系统在创造int作为整型的时候,它也不能先给整型数据进行初始化。我们可以使用系统的基本数据类型来说明变量,我们也可以使用自己创建的类类型来创建对象。在使用系统的基本数据类型来说明变量时,可以对该变量进行初始化,如:intx=5;当我们使用自己创建的类类型来创建对象时,可不可以采用类似的方式进行初始化呢?回答是肯定的。要求:对象的初始化工作须通过构造函数来完成。2、构造函数的特点:1)构造函数是类的一个成员函数,但有其特殊性。2)构造函数的函数名与类名相同。3)构造函数不能有返回值。4)构造函数的主要功能是完成对象的初始化工作。5)构造函数可以重载。在使用类名创建对象的时候,系统会自动调用构造函数,实现其“完成对象的初始化工作”的功能。回忆例题:#include<iostream.h> class Date{public:    void set(int y,int m,int d);// 赋值操作    boolisLeapYear();       // 判断闰年    voidprint();              // 输出日期private:    int year,month,day;}; void Date::set(int y,int m,int d){    year=y;    month=m;    day=d;} bool Date::isLeapYear(){    return(year%4==0&& year%100!=0)||(year%400==0);} void Date::print(){    cout<<year<<'-'<<month<<'-'<<day<<endl;} void main(){    Dated;                             //创建对象    d.set(2000,12,6);//调用set函数实现对象初始化//注意私有数据是不好直接赋值的    if(d.isLeapYear())        d.print();} 使用构造函数改写以上程序#include<iostream.h> class Date{public:    Date(int y,int m,int d);//构造函数,与类同名,不能指定返回值    boolisLeapYear();   // 判断闰年    voidprint();          // 输出日期private:    int year,month,day;}; Date::Date(int y,int m,int d){    year=y;    month=m;    day=d;} bool Date::isLeapYear(){    return(year%4==0&& year%100!=0)||(year%400==0);} void Date::print(){    cout<<year<<'-'<<month<<'-'<<day<<endl;} void main(){    Date d(2000,12,6);//创建对象时,自动调用构造函数   if(d.isLeapYear())        d.print();}1、什么是析够函数析构函数也是特殊的类成员函数,它没有返回类型,没有参数,也没有重载,不能随意调用,只有在类对象的生命期结束的时候,由系统自动调用。1)析够函数是类的一个特殊成员函数。2)析够函数的函数名取“~类名”。3)析够函数不能有返回值,也不能有函数参数。4)析够函数的主要功能是在对象消失时,执行如释放内存等清理工作。5)在对象消失时,析够函数会被自动调用。例题:#include<iostream.h> class Date{public:    Date(int y,int m,int d); // 构造函数    ~Date();               // 析构函数    voidprint();           // 输出日期private:    int year,month,day;}; Date::Date(int y,int m,int d){    year=y;    month=m;    day=d;    cout<<"Constructorcalled."<<endl;} Date::~Date(){    cout<<"Destructorcalled"<<endl;} void Date::print(){    cout<<year<<'-'<<month<<        '-'<<day<<endl;} void main(){    Date today(2007,10,17);    Date tomorrow(2007,10,18);   cout<<"today is";    today.print(); 


原创粉丝点击