2.6.1 定义Sales_data类型
尽管我们还写不出完整的Sales_item类,但是可以尝试着把那些数据元素组织到一起形成一个简单点儿的类。初步的想法是用户能直接访问其中的数据元素,也能实现一些基本的操作。
既然我们筹划的这个数据结构不带有任何运算功能,不妨把它命名为Sales_data以示与Sales_item的区别。Sales_data初步定义如下:
- struct Sales_data {
- std::string bookNo;
- unsigned units_sold = 0;
- double revenue = 0.0;
- };
我们的类以关键字struct开始,紧跟着类名和类体(其中类体部分可以为空)。类体由花括号包围形成了一个新的作用域(参见2.2.4节,第48页)。类内部定义的名字必须唯一,但是可以与类外部定义的名字重复。
类体右侧的表示结束的花括号后必须写一个分号,这是因为类体后面可以紧跟变量名以示对该类型对象的定义,所以分号必不可少:
- struct Sales_data { /* ... */ } accum, trans, *salesptr;
- // 与上一条语句等价,但可能更好一些
- struct Sales_data { /* ... */ };
- Sales_data accum, trans, *salesptr;
分号表示声明符(通常为空)的结束。一般来说,最好不要把对象的定义和类的定义放在一起。这么做无异于把两种不同实体的定义混在了一条语句里,一会儿定义类,一会儿又定义变量,显然这是一种不被建议的行为。
很多新手程序员经常忘了在类定义的最后加上分号。
类数据成员
类体定义类的成员,我们的类只有数据成员(data member)。类的数据成员定义了类的对象的具体内容,每个对象有自己的一份数据成员拷贝。修改一个对象的数据成员,不会影响其他Sales_data的对象。
定义数据成员的方法和定义普通变量一样:首先说明一个基本类型,随后紧跟一个或多个声明符。我们的类有3个数据成员:一个名为bookNo的string成员、一个名为units_sold的unsigned成员和一个名为revenue的double成员。每个Sales_data的对象都将包括这3个数据成员。
C++(www.cppentry.com)11新标准规定,可以为数据成员提供一个类内初始值(in-class initializer)。创建对象时,类内初始值将用于初始化数据成员。没有初始值的成员将被默认初始化(参见2.2.1节,第43页)。因此当定义Sales_data的对象时,units_sold和revenue都将初始化为0,bookNo将初始化为空字符串。
对类内初始值的限制与之前(参见2.2.1节,第43页)介绍的类似:或者放在花括号里,或者放在等号右边,记住不能使用圆括号。
7.2节(第268页)将要介绍,用户可以使用C++(www.cppentry.com)语言提供的另外一个关键字class来定义自己的数据结构,到时也将说明现在我们使用struct的原因。在第7章学习与class有关的知识之前,建议读者继续使用struct定义自己的数据类型。
2.6.1节练习
练习2.39:编译下面的程序观察其运行结果,注意,如果忘记写类定义体后面的分号会发生什么情况?记录下相关信息,以后可能会有用。
- struct Foo { /* 此处为空 */ } // 注意:没有分号
- int main()
- {
- return 0;
- }
练习2.40:根据自己的理解写出Sales_data类,最好与书中的例子有所区别。