第四讲:具有合法状态的对象

只能通过成员函数访问对象的成员数据保证了对象状态的合法性,即不可能把对象的成员变量赋值为非法的数据。分析下面的程序。

#include<stdio.h>

#include<string.h>

class Student

{

public:

       void setData(char *pName, int se, int ye,int mo, int da, float gr)

       {

              strcpy(name, pName);

              if(se==0 || se==1)

                     sex = se;

              else

                     sex = 1;

              if(ye>0)

                     year = ye;

              else

                     year = 2000;

              if(mo>0 && mo<13)

                     month = mo;

              else

                     month = 1;

              if(da>0 && da<31)

                     day = da;

              else

                     day = 1;

              if(gr>=0 && gr<=100)

                     grade = gr;

              else

                     grade = 0;

       }

       void showMessage()

       {

              printf("姓名:%s\n",name);

              printf("性别:%s\n",sex==1 ? "男" : "女");

              printf("出生日期:%d年%d月%d日\n",year, month, day);

              printf("英语成绩:%.1f\n", grade);

       }

private:

       char name[10];

       int sex; //1为男0为女

       int year;

       int month;

       int day;

       float grade;//英语成绩

};

int main()

{

       Studentzhang3;

       zhang3.showMessage();

       return0;

}

程序的执行结果为:

姓名:烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫?

性别:女

出生日期:-858993460年-858993460月-858993460日

英语成绩:-107374176.0

由程序的输出结果可知,对象zhang3并没有处于合法的状态。无论怎样使用对象(即使用非法的数据给对象赋值),对象都会处于合法的状态,但在对象“产生”后至“使用”前一起处于“非法”的状态。如何保证对象一产生就处于合法的状态呢?

定义对象时用合法的数据给对象赋值。

类中有一种特殊的成员函数,即构造函数。定义对象时,构造函数会被自动调用,因此,可以通过构造函数保证对象的合法状态。切记,只要有对象产生,必定会有构造函数执行。上面的程序中,也就是说,编译系统帮忙自动为程序员调用了构造函数。构造函数应该什么样子呢?

名字必须特殊,类属于用户定义数据类型,如果程序员可以随意为构造函数命名,编译系统就不可能找到构造函数,也就不可能替程序员调用构造函数了。构造函数就是与类名相同的函数。

构造函数没有返回值,这很自然,编译系统帮忙调用的函数要返回值有什么用?构造函数不用void表示没有返回值,直接就是函数名。可以用下面的代码定义一个类Student构造函数。

Student(){}

疑问在于示例程序中Student类并没有定义构造函数,对象定义语句Student zhang3;执行时,构造函数怎样自动执行呢?

编译系统会为没有定义构造函数的类定义一个“默认”构造函数,不过编译系统定义的构造函数什么也不做,如上面的构造函数所示。

上面程序中在对象生成时,虽然执行了编译系统定义的构造函数,但生成后对象还是处于非法的状态,因此需要程序员为类定义一个“合适”的构造函数。修改程序中类的定义如下:

class Student

{

public:

       Student()

       {

              strcpy(name, "NoName");

              sex = 1;

              year = month = day = 1;

              grade = 0;

       }

       ......

};

修改后程序的运行结果如下:

姓名:NoName

性别:男

出生日期:1年1月1日

英语成绩:0.0

构造函数可以重载。可以再定义一个构造函数,

Student(char *pName, int se, int ye, int mo,int da, float gr)

{

       setData(pName,se, ye, mo, da, gr);

}

则可以用语句Student li4("Li4", 1, 2000, 10, 10, 95);定义一个名为li4的对象。

有了构造函数,程序员可以保证对象一产生就处于合法的状态,而且对象也可以初始化了。

下面的程序会出现语法错误。

#include<stdio.h>

#include<string.h>

class Student

{

public:

       Student(char *pName, int se, int ye, intmo, int da, float gr)

       {

              setData(pName, se, ye, mo, da,gr);

       }

       void setData(char *pName, int se, int ye,int mo, int da, float gr)

       {

              strcpy(name, pName);

              if(se==0 || se==1)

                     sex = se;

              else

                     sex = 1;

              if(ye>0)

                     year = ye;

              else

                     year = 2000;

              if(mo>0 && mo<13)

                     month = mo;

              else

                     month = 1;

              if(da>0 && da<31)

                     day = da;

              else

                     day = 1;

              if(gr>=0 && gr<=100)

                     grade = gr;

              else

                     grade= 0;

       }

       void showMessage()

       {

              printf("姓名:%s\n",name);

              printf("性别:%s\n",sex==1 ? "男" : "女");

              printf("出生日期:%d年%d月%d日\n",year, month, day);

              printf("英语成绩:%.1f\n", grade);

       }

private:

       char name[10];

       int sex; //1为男0为女

       int year;

       int month;

       int day;

       float grade;//英语成绩

};

int main()

{

       Studentzhang3;

       zhang3.showMessage();

       Student li4("Li4", 1, 2000, 10,10, 95);

       li4.showMessage();

       return 0;

}

语句Student zhang3;执行时需执行默认构造函数,而类中却没有(参数为空)默认构造函数。当类中有了构造函数后,编译系统就不会为类自动生成默认构造函数了。没有了默认构造函数,类似Student zhang3;的语句就无法执行了,所以就出现了语法错误。

解决方案有两个。一是定义一个默认构造函数。二是为构造函数的每个参数设置缺省值。如Student(char *pName="NoName", int se=1, int ye=1, intmo=1, int da=1, float gr=0)

       {

              setData(pName, se, ye, mo, da,gr);

       }
展开阅读全文

没有更多推荐了,返回首页