首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

C++中,通过定义class来自定义数据类型。类定义了该类型的对象包含的数据和该类型的对象可以执行的操作。标准库类型stringistreamostream都定义成类。

C++对类的支持非常丰富——事实上,定义类是如此重要,我们把第三到第五部分对应于用来描述C++对类及类操作的支持。

在第1章中,我们使用Sales_item类型来解决书店问题。使用Sales_item类型的对象来记录对应于特定ISBN的销售数据。在这节中,我们先了解如何定义简单的类,如Sales_item类。

1. 设计类从其操作开始

每个类都定义了一个接口interface和一个实现implementation。接口包括我们期望使用该类的代码执行的操作。实现一般包括该类所需要的数据。实现还包括用来定义该类但又不作一般性使用的函数。

定义类时,通常先定义该类的接口,即该类所提供的操作。通过这些操作,可以决定该类完成其功能所需要的数据,以及是否需要定义一些函数来支持该类的实现。

我们将要定义的类型所支持的操作,就是我们在第1章中所用到的操作。这些操作如下(参见1.5.1节):

l 加法符,将两个Sales_item相加。

l 输入和输出操作符,读和写Sales_item对象。

l 赋值操作符,把Sales_item对象赋给另一个Sales_item对象。

l same_isbn函数,检测两个对象是否指同一本书。

在学完怎样定义函数和操作符后,我们将会在第7章和第14章看到该怎样来定义这些操作。虽然现在不能实现这些函数,但通过思考这些操作必须要实现的功能,我们可以看出该类需要什么样的数据。Sales_item类必须

(1) 记录特定书的销售册数。

(2) 记录该书的总销售收入。

(3) 计算该书的平均售价。

察看以上所列出的任务,可以知道需要一个unsigned类型的对象来记录书的销售册数,一个double类型的对象来记录总销售收入,然后可以用总收入除以销售册数计算出平均售价。因为我们还想知道是在记录哪本书,所以还需要定义一个string类型的对象来记录书的ISBN

2. 定义Sales_item

很明显,我们需要能够定义一种包含这三个数据元素和在第1章所用到的操作的数据类型。在C++语言中,定义这种数据类型的方法就是定义类:

class Sales_item {

public:

    // operations on Sales_item objects will go here

private:

    std::string isbn;

    unsigned units_sold;

    double revenue;

};

类定义以关键字class开始,其后是该类的名字标识符。类体位于花括号里面。花括号后面必须要跟一个分号。

编程新手经常会忘记类定义后面的分号,这是个很普遍的错误!

类体可以为空。类体定义了组成该类型的数据和操作。这些操作和数据是类的一部分,也称为类的成员member。操作称为成员函数(1.5.2节),而数据则称为数据成员data member

类也可以包含0个到多个privatepublic访问标签access label。访问标签控制类的成员在类外部是否可访问。使用该类的代码可能只能访问public成员。

定义了类,也就定义了一种新的类型。类名就是该类型的名字。通过命名Sales_item类,表示Sales_item是一种新的类型,而且程序也可以定义该类型的变量。

每一个类都定义了它自己的作用域(2.3.6节)。也就是说,数据和操作的名字在类的内部必须唯一,但可以重用定义在类外的名字。

3. 类的数据成员

定义类的数据成员和定义普通变量有些相似。我们同样是指定一种类型并给该成员一个名字:

std::string isbn;

unsigned units_sold;

double revenue;

这个类含有三个数据成员:一个名为isbnstring类型成员,一个名为units_soldunsigned类型成员,一个名为revenuedouble类型成员。类的数据成员定义了该类类型对象的内容。当定义Sales_item类型的对象时,这些对象将包含一个string型变量,一个unsigned型变量和一个double型变量。

定义变量和定义数据成员存在非常重要的区别:一般不能把类成员的初始化作为其定义的一部分。当定义数据成员时,只能指定该数据成员的名字和类型。类不是在类定义里定义数据成员时初始化数据成员,而是通过称为构造函数(2.3.3节)的特殊成员函数控制初始化。我们将在7.7.3节定义Sales_item的构造函数。

4. 访问标签

访问标签控制着使用该类的代码是否可以使用给定的成员。类的成员函数可以使用类的任何成员,而不管其访问级别。访问标签publicprivate可以多次出现在类定义中。给定的访问标签应用到下一个访问标签出现为止。

类中public部分定义的成员在程序的任何部分都可以访问。一般把操作放在public部分,使得程序的任何代码都可以执行这些操作。

不是类的组成部分的代码不能访问private成员。通过设定Sales_item的数据成员为private,可以保证对Sales_item对象进行操作的代码不能直接操纵其数据成员。就像我们在第1章编写的程序那样,程序不能访问类中的private成员。Sales_item类型的对象可以执行那些操作,但是不能直接修改这些数据。

5. 使用struct关键字

C++支持另一个关键字struct,它也可以定义类类型。struct关键字是从C语言中继承过来的。

如果使用class关键字来定义类,那么定义在第一个访问标签前的任何成员都隐式指定为private;如果使用struct关键字,那么这些成员都是public。使用class还是struct关键字来定义类,仅仅影响默认的初始访问级别。

可以等效地定义Sales_item类为:

struct Sales_item {

    // no need for public label, members are public by default

    // operations on Sales_item objects

private:

    std::string isbn;

    unsigned units_sold;

    double revenue;

};

本例的类定义和前面的类定义只有两个区别:这里使用了关键字struct,并且没有在花括号后使用关键字publicstruct的成员都是public,除非有其他特殊的声明,所以就没有必要添加public标签。

classstruct关键字定义类的唯一差别在于默认访问级别默认情况下struct的成员为publicclass的成员为private

习题                                                              

习题2.28  编译以下程序,确定你的编译器是否会警告遗漏了类定义后面的分号。

   class Foo  {

            // empty

     } // Note: no semicolon

     int main()

     {

          return 0;

     }

如果编译器的诊断结果难于理解,记住这些信息以备后用。

习题2.29  区分类中的public部分和private部分。

习题2.30  定义表示下列类型的类的数据成员:

        (a) 电话号码                               (b) 地址

        (c) 员工或公司                            (d) 某大学的学生

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论