按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
l Class CBaloon;
l CBaloon Baloon1;
l CBaloon Baloon2;
l CBaloon Baloon3;
在上面的代码 中,我们声明了一个类CBaloon,这是所有狒狒
对象的抽象,然后,我们使用类来创建了三个不同的实例对
象Baloon1、Baloon2和Baloon3。
然而,尽管类和对象是两个意义不同的概念,但是,它们在
C++语言中是紧密相关的,这使得很多的文档 (包括Visual
C++的联机文档)在有些时候也不加 区分的混用这两个术语。
读者根据相应的上下文,应该能够很方便的辨明它们具体所
指的内容究竟是类还是类的实例对象。
在随后的小节中,我们将讲述如何在C++中实现上面所说的面向对象
的编程概念。
第二节 类的声明和定义
本节讲述在声明和定义类及类中的成员变量和成员函数所需注意的问
题。在本章中,我们使用了传统的C/C++编程风格,即每一个程序都
以一个名为main的主函数为入口,过去常见的MS…DOS应用程序即是这
样的。众所周知,Visual C++ 5。0不支持16位MS…DOS编程,但这并不
意味着我们必须放弃这种编程模式。事实上,我们仍然可以在Visual
C++ 5。0中编译和调试在本章中出现的所有程序,方法是使用Win32
Console Application (Win32控制台应用程序)来编译它们,Win32控
制台API提供了字符方式的应用程序的编程接口,并且,我们仍可以
使用过去所熟知的以main函数为入口的编程方式。除此之外,Win32
平台为控制台应用程序提供了虚拟的一个标准输入和输出设备 (由于
Windows程序共享屏幕和其它所有设备,因此不存在在DOS中的那种标
准输入和输出设备),这样,我们可以使用标准的C语言输入输出函数
scanf和printf,还可以使用标准的C++语言输入和输出流cin和
…………………………………………………………Page 47……………………………………………………………
cout。关于控制台应用程序的内容,可以参考本书的相关章节。
2。2。1 类及其成员变量和成员函数的声明和定义
在C++中,存在三种类类型:类、结构和联合,它们分别使用三个关
键字来声明和定义类:class、struct和union。表2。1给出了不同类
类型之间的差别。
表2。1 三种不同类型的类:类、结构和联合
类 结构 联合
声明和定义时使用 class struct union
的关键字
默认的成员访问权 私有 公有 公有
限
使用限制 无 无 同时只能使用一
个成员
由于联合的特殊性,我们将在后面的内容中讲述它。下面给出一个使
用class来定义类的示例:
class CCircle
{
public:
unsigned Radius;
CPoint Center;
};
下面我们使用关键字struct来定义类CPoint:
struct CPoint
{
unsigned x;
unsigned y;
};
…………………………………………………………Page 48……………………………………………………………
l 注意:
l 请不要忘了在类定义的第二个大括号 “}”之后加上一个分号,否
则编译时会 出现一堆莫名其妙的错,并且没有一个错误会告诉你
是在定义类的时候少加了一个分号(也许它会告诉你别的什么地方
少了一个分号,但事实上那里什么错误也没有)。也许有人认为这
并非是一个值得强调的问题,然而事实上绝大多数初学者 (甚至包
括一些有经验的程序员)都会 由于疏忽大意而犯了这样的错误,并
且在修正它的时候花费了大量的时间却依然没有发现所有的问题
实际上只是由一个小分号造成的。
细心的读者会注意到,在类CCircle的定义中我们使用了public关键
字,而在类CPoint的定义中却没有使用。这是因为在使用struct定义
的类中,成员的默认访问权限为公有,因此不需要使用public关键
字,而对于使用class关键字来定义的类,由于其成员的默认访问权
限为私有,因此必须使用关键字public来将成员Radius和Center的访
问权限设置为公有。一般来说,一个类中总是包括了一定数量的公有
成员,没有公有成员的类由于没有提供任何接口,事实上没有什么
用。
对于同一个类,可以使用关键字class来定义,也可以使用关键字
struct来定义。对于上面的例子,我们将类CCircle改用关键字
struct来定义,而将类CPoint改用关键字class来定义如下:
struct CCircle
{
unsigned Radius;
CPoint Center;
};
class CPoint
{
public:
unsigned x;y;
};
现在我们来考虑一下,如果在同一个文件中定义类CCircle和类
…………………………………………………………Page 49……………………………………………………………
CPoint,并采用如上面的代码,会遇到什么问题。我们看到,在类
CCircle中定义了类CPoint的实例对象Center,然而,在定义实例对
象Center的时候,我们还没有给出类CPoint的定义,这时,在编译时
就会出现错误。因此,我们应该采用下面的顺序:
struct CPoint
{
unsigned x;
unsigned y;
};
class CCircle
{
public:
unsigned Radius;
CPoint Center;
};
以确保在使用类CPoint这前已经对它进行了定义。如果我们在类
CPoint中添加一个成员函数IsInCircle来判断一个点是否在圆内,如
下面的代码所示:
struct CPoint
{
unsigned x;
unsigned y;
bool IsInCircle(CCircle *Circle)
{
return ( ((x…Circle…》Center。x)*(x…Circle…》Center。x)
+(y…Circle…》Center。y)*(y…Circle…》Center。y))
Radius*Circle…》Radius );
}
…………………………………………………………Page 50……………………………………………………………
};
这真是一件很不幸的事情。为什么这样说呢?请看上面的代码,我们
在IsInCircle成员函数中又使用到了类CCircle,而按照我们在前面
所给出的代码,类CCircle是在类CPoint之后进行定义的,那么,将
类CPoint放到类CCircle之后定义行不行呢?答案是不行的,不要忘
了我们还在类CCircle中定义了一个类型为CPoint的数据成员
Center。
使用类的声明可以解决上面所遇到的两难问题。为了在定义类
CCircle之前先引用类CCircle的类名,我们可以在类CPoint之前添加
如下的代码:
Class CCircle;
l 注意:
l 不能在末尾加上一对大括号,因为这样的话,上面的代码就会被
当作一个类的定义,这时,在同一文件作用域中就会出现了同一
类的两个定义,而这在C++中是不允许的,一个类可以有多个声
明,但是它只能有一个定义,对于函数也是这样。
上面的代码和类的定义的差别在于它没有一对大括号 “{}”,这样,
我们就可以在定义类CCircle先定义指向一个类CCircle的对象的指针
和引用。但是,这时CPoint的代码不能像上面那样写,这是因为在成
员函数IsInCircle中我们使用了类CCircle中定义的数据成员,而在
此之前编译器只知道用以使用一个名为CCircle的类,但是不知道这
个类中包括了什么样的成员,因此上面的代码在编译时通不过。
如果解决所遇到的新问题呢?回过头来看类CPoint的定义,我们在定
义类的同时定义了成员函数IsInCircle,联想到C语言中的函数,我
们可以很自然的想到,可不可以选声明成员函数IsInCircle,然后再
定义它呢?如果可以这样的话,我们就可以在类CPoint的定义中先声
明成员函数IsInCircle,然后在定义了类CCircle之后再添加成员
IsInCircle的定义。
事实上我们正是基于这个想法来解决问题的。我们的确可以先在类
CPoint的定义中声明成员函数IsInCircle,然后在后面添加它的定
义,完整的代码如下:
#include
class CCircle;
…………………………………………………………Page 51……………………………………………………………
struct CPoint
{
unsigned x;
unsigned y;
bool IsInCircle(CCircle *Circle);
};
class CCircle
{
public:
unsigned Radius;
CPoint Center;
};
bool CPoint::IsInCircle(CCircle *Circle)
{
return ( ((x…Circle…》Center。x)*(x…Circle…》Center。x)
+(y…Circle…》Center。y)*(y…Circle…》Center。y))
Radius*Circle…》Radius );
}
void main()
{
CPoint Center;
CPoint Point;
CCircle Circle;
Center。x=0;
Center。y=0;
Point。x=2;
…………………………………………………………Page 52……………………………………………………………
Point。y=3;
Circle。Radius=3;
Circle。Center=Center;
if (Point。IsInCircle(&Circle))
cout