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

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

#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);

       }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如何用Java实现推箱子是一款经典电子游戏,爱丽丝很喜欢玩,但是她有点玩腻了,现在她想设计一款拉箱子游戏。 拉箱子游戏需要玩家在一个 N×M 的网格地图中,控制小人上下左右移动,将箱子拉到终点以获得胜利。 现在爱丽丝想知道,在给定地形(即所有墙的位置)的情况下,有多少种不同的可解的初始局面。 【初始局面】 的定义如下: 初始局面由排列成 N×M 矩形网格状的各种元素组成,每个网格中有且只有一种元素。可能的元素有:空地、墙、小人、箱子、终点。 初始局面中有且只有一个小人。 初始局面中有且只有一个箱子。 初始局面中有且只有一个终点。 【可解】 的定义如下: 通过有限次数的移动小人(可以在移动的同时拉箱子),箱子能够到达终点所在的网格。 【移动】 的定义如下: 在一次移动中,小人可以移动到相邻(上、下、左、右四种选项)的一个网格中,前提是满足以下条件: 小人永远不能移动到 N×M 的网格外部。 小人永远不能移动到墙上或是箱子上。 小人可以移动到空地或是终点上。 【拉箱子】 的定义如下: 在一次合法移动的同时,如果小人初始所在网格沿小人移动方向的反方向上的相邻网格上恰好是箱子,小人可以拉动箱子一起移动,让箱子移动到小人初始所在网格。 即使满足条件,小人也可以只移动而不拉箱子。 输入格式 第一行两个正整数 N 和 M,表示网格的大小。 接下来 N 行,每行 M 个由空格隔开的整数 0 或 1 描述给定的地形。其中 1 表示墙,0 表示未知的元素,未知元素可能是小人或箱子或空地或终点,但不能是墙。 输出格式 输出一个正整数,表示可解的初始局面数量。
02-06

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值