C++回顾——数据抽象

一、动态内存分配
堆是很大的内存块,用以在运行时分配一些小的存储空间。在写程序时,如果还不知道所需内存的大小,就可使用堆。在标准C中,动态内存分配函数包括malloc()、calloc()、realloc()、free()。C++中,使用new和delete。任何时候申请内存都有可能失败,要判断内存是否分配成功。
注意,堆管理器是相当简单的,它给出一块内存,而当用delete释放时又把它收回。这里没有提供能压缩堆获得较大的空闲块的堆压缩内部工具。如果程序反复分配和释放堆存储,最终将会产生大量的空闲内存碎片,但却没有足够大的块能分配所需的内存。堆压缩器使程序更复杂,因此要前后移动内存块(锁定内存后堆压缩器就不能移动它了),所以指针应保持正确的值。在C值,可以赋void*给任何指针(C对类型信息不挑剔,它允许未明确类型的指针赋给一个明确类型的指针);但在C++中,是不允许的(C++中有严格的类型检查,C++允许将任何类型的指针赋给void*)。

二、基本对象
把函数放进结构体中是从C到C++中的根本改变。在C中,struct是数据的凝聚(它将数据捆绑在一起);而C++中,struct既能描述属性,又能描述行为。
对象就是变量,是一块存储区(能存放数据,而且还隐含着对这些数据进行处理的操作)。

三、抽象数据类型
封装(encapsulation):将数据连同函数捆绑在一起,用于创建新的数据类型。
抽象数据类型:从问题空间抽象概念到解空间。对抽象数据类型的检查就像对内建类型的检查一样严格。
事实上,面向对象编程可以总结为一句话,“向对象发送消息”。
对象的基本规则之一是每个对象必须有一个唯一的地址,因此,无数据成员的结构总应当有最小的非零长度(在VS2008编译器中是1)。

四、头文件形式
1、头文件的重要性
头文件是存放接口规范的地方(是我们和我们的库的用户之间的合约,它描述了我们的数据结构,为函数调用规定了参数和返回值)。在C中,允许不使用头文件,而是简单地随手声明这个函数(过去这样做是为了通过避免打开和包含这个文件而略微提高编译器的速度)。在C++中,头文件的使用变得非常明显。
头文件的使用可以确保整个系统中的声明一致,而且可以确保声明和定义匹配。
编写头文件的基本原则是“只限于声明”(不涉及通过生成代码或创建变量而分配存储的任何信息),这是因为头文件一般会包含在项目的几个翻译单元中,如果一个标识符在多于一处被分配存储,那么连接器就报告多次定义错误。
C和C++都允许重声明函数,只要两个声明匹配即可,但是两者都不允许重声明结构。

2、预处理器指示#define、#ifdef和#endif
预处理器指示#define可以用来创建编译时标记。#ifdef 后面的代码将包含在发送给编译器的包中,当预处理器遇到语句#endif时包含终止。#ifdef/#endif对可以相互嵌套。#define的反意是#undef,它将使得使用相同变量的#ifdef语句得到假值。#undef还引起预处理器停止使用宏。#ifdef的反意是#ifndef。

3、头文件的标准
通过测试预处理器的标记来检查头文件是否已经包含在cpp文件中。如果这个标记没有设置,这个文件没有包含,则应当设置它。下面显示头文件的样子:

#ifndef HEADER_FLAG
#define HEADER_FLAG
// Type declaration here...
#endif // HEADER_FLAG

头文件第一次被包含,这个头文件的内容将被包含在预处理器中。对于在单个编译单元中的所有后续的包含,该类型声明被忽略。防止多次包含的这些预处理器语句常常称为包含守卫(include guard)。命名空间的使用指令不能放在头文件中(否则将很容易实际上在各处“关闭”名字空间)。

猜你喜欢

转载自blog.csdn.net/zlanbl085321/article/details/80883393