按照封装与信息隐藏的原则,除非特别需要,类中的数据成员需要设置为私有。由此带来的问题是,在类外如何访问这些私有成员?下面4段程序概括了常用的方法。请仔细阅读下面的程序,在阅读过程中,画出对象、变量在内存中的表示图,写出这些程序的运行结果(包括变量的变化过程及程序的最终输出),达到彻底理解这些机制的目标。
(1)通过公共函数为私有成员赋值
class Test {private: int x, y; public: void setX(int a) {x=a;} void setY(int b) {y=b;} void printXY(void) {cout<<"x="<<x<<'\t'<<"y="<<y<<endl;} } ; void main(void) { Test p1,p2; p1.setX(3);p1.setY(5); p1.printXY( ); }(2)利用指针访问私有数据成员
class Test {private: int x,y; public: void setX(int a) {x=a;} void setY(int b) {y=b;} void getXY(int *px, int *py) {*px=x;*py=y;}//提取x,y值 }; void main(void) { Test p1,p2; p1.setX(3);p1.setY(5); int a,b; p1.getXY(&a,&b); //将 a=x, b=y cout<<a<<'\t'<<b<<endl; }(3)利用函数访问私有数据成员
class Test {private: int x,y; public: void setX(int a) {x=a;} void setY(int b) {y=b;} int getX(void) {return x;} //返回x值 int getY(void) {return y;} //返回y值 }; void main(void) { Test p1,p2; p1.setX(3);p1.setY(5); int a,b; a=p1.getX( ); b=p1.getY(); cout<<a<<'\t'<<b<<endl; }
(4)利用引用访问私有数据成员
class Test { private: int x,y; public: void setX(int a) {x=a;} void setY(int b) {y=b;} void getXY(int &px, int &py) //引用 {px=x;py=y;} //提取x,y值 }; void main(void) { Test p1,p2; p1.setX(3);p1.setY(5); int a,b; p1.getXY(a, b); //将 a=x, b=y cout<<a<<'\t'<<b<<endl; }
第二部分 上机实践
【项目1 - 三角形类】下面设计一个三角形类,请给出各成员函数的定义
/* * 程序的版权和版本声明部分 * Copyright (c)2012, 烟台大学计算机学院学生 * All rightsreserved. * 文件名称: object.cpp * 作者:原承旭 * 完成日期: 2013年3 月 日 * 版本号: v1.0 * 输入描述:无 * 问题描述:设计求三角形周长和面积的类。 * 程序输出:三角形的周长和面积 */ #include<iostream> using namespace std; class Triangle {public: void Setabc(doublex, doubley, doublez);//置三边的值,注意要能成三角形 void Getabc(double*x, double*y, double*z);//取三边的值 doublePerimeter(void);//计算三角形的周长 doubleArea(void);//计算并返回三角形的面积 private: doublea,b,c; //三边为私有成员数据 }; int main(void) { Triangle Tri1; //定义三角形类的一个实例(对象) Tri1.Setabc(4,5,6); //为三边置初值 doublex,y,z; Tri1.Getabc (&x,&y,&z); //将三边的值为x,y,z赋值 cout<<"三条边为:"<<x<<'\t'<<y<<'\t'<<z<<endl; cout<<"三角形的周长为:"<< Tri1.Perimeter()<<'\t'<<"面积为:"<< Tri1.Area()<<endl; return 0; } //请在下面定义Triangle类中的各个成员函数
提示:调试程序过程中,请记录下出现的错误信息,并在发表的博文中写在总结部分。总结出真知,多此一举,多收一斗。
【项目2 - 三角形类】程序功能同项目1,main()函数如下,请定义类Triangle,其中逻辑特别简单的set和get成员函数,可以处理为内置成员函数,直接在类内定义。
int main() { Triangle tri1; //定义三角形类的一个实例(对象) double x,y,z; cout<<"请输入三角形的三边:"; cin>>x>>y>>z; tri1.setA(x);tri1.setB(y);tri1.setC(z); //为三边置初值 if(tri1.isTriangle()) { cout<<"三条边为:"<<tri1.getA()<<','<<tri1.getB()<<','<<tri1.getC()<<endl; cout<<"三角形的周长为:"<< tri1.perimeter()<<'\t'<<"面积为:"<< tri1.area()<<endl; } else cout<<"不能构成三角形"<<endl; system("pause"); return 0; }提示:调试程序过程中,请记录下出现的错误信息,并在发表的博文中写在总结部分。
【项目3 - 程序的多文件组织】当程序规模变大后,一个程序用多个文件组织,便于组织生产。这样,不必每次都重复对所有代码进行编译,而只需编译一次即可。把编译后所形成的目标文件保存起来,以后在需要时把它调出来直接与程序的目标文件相连接即可。
C++中一种常用的做法是,独立出一个头文件来。正确使用头文件带来的好处包括:支持代码的局部单独编译,尤其对类及成员函数声明;保证所有文件使用给定实体的同一声明;当声明需要修改时,只有头文件需要更新。使用头文件的时候,头文件只用于声明,而不是定义,头文件一般含有支持分别编译所需的类定义及变量和函数的声明。另外,一些const对象要定义在头文件中。类的成员函数定义在头文件中只有一个例外,那就是内置(inline)成员函数需要定义在头文件中。
下面是本项目的要求:
利用多文件组织,完成项目2。其中,项目包括3个文件:
- 主文件: main.cpp,用于定义main()函数
- 头文件: triangle.h,头文件
- 类定义文件: triangle.cpp,用于定义类Triangle
【项目4 - 正整数类】设计一个“正整数”类,并通过一系列的成员函数对其性质进行做出判断或列出相关联的数值。下面给出类声明,请实现各成员函数。另外,模仿已经给出的main()函数,完成你所设计的各个成员函数的测试。如果时间有限,不必实现所有成员函数。
#include<iostream> using namespace std; class NaturalNumber {private: int n; public: void setValue (int x);//置数据成员n的值,要求判断是否是正整数 int getValue(); //返回私有数据成员n的值 bool isPrime(); //判断数据成员n是否为素数,是返回true,否则返回false void printFactor(); //输出数据成员n的所有因子,包括1和n自身 bool isPerfect(); //判断数据成员n是否为完全数。若一个正整数n的所有小于n的因子之和等于n, 则称n为完全数, 如6=1+2+3是完全数。 bool isReverse(int x);//判断形式参数x是否为数据成员n的逆向数(例321是123的逆向数)。 bool isDaffodil(int x); //判断形式参数x是否是水仙花数。水仙花数的各位数字立方和等于该数,如153=1*1*1+5*5*5+3*3*3 void printDaffodils(); //显示所有大于1,且小于数据成员n的水仙花数; }; void main(void) { NaturalNumber nn; //定义类的一个实例(对象) nn.setValue (6); cout<<nn.getValue()<<(nn.isPrime()?”是”:”不是”)<<”素数” <<endl; nn.setValue (37); cout<<nn.getValue()<<(nn.isPrime()?”是”:”不是”)<<”素数” <<endl; nn.setValue (84); cout<<nn.getValue()<<”的因子有:”; printFactor(); //随着成员函数的实现,增加代码以完成相关的测试。注意判断类的成员函数需要测试是或否两种情况…… } //请在下面定义类中的各个成员函数【项目4扩展(选做)】将项目4也用多文档的项目组织起来,体会这样做的好处。
【项目5 - 数组作数据成员】阅读教材P255例8.4,注意到类中的数据成员可以是数组。设计一个工资类(Salary),其中的数据成员有:double型数组salary[50](实际人数可以少于50,固定取50可能造成空间浪费),整型值number表示的职工人数。在main函数中调用你自己设计好的成员函数完成下面的功能:
(1)输入职工工资,工资保存到salary数组中,实际人数保存到number中(输入-1标志着工资输入结束);
(2)给每个人涨100元工资;
(3)对涨后的工资进行排序;
(4)输出排序后的工资。
提示:上述每一个功能都需要设计成一个成员函数。
【项目5扩展1(选做)】使用salary[50]有限制,实际人数少浪费空间,人数多时无法完成任务。程序执行中先输入职工人数,然后利用教材P217所讲的动态分配内存的运算符new,开辟一个大小正好的连续空间,完成上面的工作(排序需要采用指针完成)。
【项目5扩展2(选做)】手工输入工资?!太让人不能忍受了。现给出包含了500个职工工资的文件salary.txt,从文件中读数据,完成上面的工作。
【项目5扩展3(选做)】增加一个成员函数,将排序后结果保存到一个文件中。
课程主页在:http://blog.csdn.net/sxhelijian/article/details/7910565