Chapter2,Section2.6——Defining Our Own Data Structures
定义自己的数据类型
在C++里面通过定义类class来定义自己的数据结构。
我们可以用如下方式来定义自己的数据结构:
struct Sales_data {
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
我们的类以关键字struct开始,后面是类的名字,接着在花括号内的是类体(可能为空)。类体里面定义的变量的名字必须与类名不同,但是可以与类外的变量重名。花括号末尾一定要加上;分号,这样我们就能在类体外定义变量了。有时会在定义类时在花括号后面直接定义变量,这时要在变量定义结束时加上分号。但是建议将类的定义与变量的定义分开。
例:Struct Sales_data { /* ... */ } accum, trans, *salesptr;类和变量定义在一起。
类和变量分开定义(建议):
Struct Sales_data { /* ... */ };
Sales_data accum, trans, *salesptr;
一定要注意在末尾加上分号!
类体里面可以定义许多的类成员。定义类的数据成员时与定义普通变量一样,一个基本类型加上许多的变量名字。
在新标准下,我们可以使用类内初始化来初始化数据成员。没有被初始化的数据成员是默认值。(整型0,string类型为空串)。类内初始化非常严格,它只能使用花括号{}形式或者=形式,不能使用小括号()形式。
以后我们还会介绍另一个关键字来定义我们自己的数据结构,在此就先介绍struct方式。
头文件
通常将类的定义写在头文件里面,以方便多个类来进行使用。头文件的名字通常和相应的类名相同。
头文件通常包含一些在任何给定文件只能被定义一次的实体(例如类定义,const,和constexpr变量)。
有时候一个头文件里面也可能包含另一个头文件。
当一个头文件更新后,源文件必须进行重新的编译来获得新的或者改变了的声明。
简要介绍预处理程序
预处理程序确保了多次包含一个头文件是安全的。C++从C里面继承来的预处理程序在编译之前运行并且改变了而我们程序的源文本。我们现在的程序已经依赖了一个预处理程序——#include。当预处理程序遇见#include时,它就将#include替换成具体的头文件。
C++程序也允许预处理程序定义头文件保护符——header guards。头文件保护符依赖于我们的预处理程序变量。预处理程序变量有两种状态——定义和未定义。#define指令带来了一个名字并将这个定义为预处理程序变量。有另外的两个指令用来检查一个给定的预处理程序变量是否被定义。#ifdef当变量已经定义时,它是true。#ifndef当变量未被定义时是true。一旦测试是true,任何在#ifdef和#ifndef后面的都要进行处理直到遇到#endif。
注意:预处理程序变量命名不遵守C++作用域命名规则。
预处理程序变量,包括头文件保护符的名字必须在程序中是唯一的。为了确保唯一性,通常将保护符的名字以头文件中的类名为基础。为了在程序中避免命名冲突,预处理变量通常都是大写字母。
头文件中最好有头文件保护符,即使该头文件没有被任何其他的文件包含。当你习惯性地进行头文件保护符的定义时,就不用考虑是否真的需要头文件保护符了。