目录
多文件结构和编译预处理命令
C++程序的一般组织结构
l 一个工程可以划分为多个源文件:
n 类声明文件(.h文件)
n 类实现文件(.cpp文件)
n 类的使用文件(main()所在的.cpp文件)
l 利用工程来组合各个文件。
例 5-10 多文件的工程
//文件1,类的定义,Point.h
class Point { //类的定义
public: //外部接口
Point(int x = 0, int y = 0) : x(x), y(y) { }
Point(const Point &p);
~Point() { count--; }
int getX() const { return x; }
int getY() const { return y; }
static void showCount(); //静态函数成员
private: //私有数据成员
int x, y;
static int count; //静态数据成员
};
//文件2,类的实现,Point.cpp
#include "Point.h"
#include <iostream>
using namespace std;
int Point::count = 0; //使用类名初始化静态数据成员
Point::Point(const Point &p) : x(p.x), y(p.y) {
count++;
}
void Point::showCount() {
cout << " Object count = " << count << endl;
}
//文件3,主函数,5_10.cpp
#include "Point.h"
#include <iostream>
using namespace std;
int main() {
Point a(4, 5); //定义对象a,其构造函数使count增1
cout <<"Point A: "<<a.getX()<<", "<<a.getY();
Point::showCount(); //输出对象个数
Point b(a); //定义对象b,其构造函数回使count增1
cout <<"Point B: "<<b.getX()<<", "<<b.getY();
Point::showCount(); //输出对象个数
return 0;
}
外部变量
l 如果一个变量除了在定义它的源文件中可以使用外,还能被其它文件使用,那么就称这个变量是外部变量。
l 文件作用域中定义的变量,默认情况下都是外部变量,但在其它文件中如果需要使用这一变量,需要用extern关键字加以声明。
外部函数
l 在所有类之外声明的函数(也就是非成员函数),都是具有文件作用域的。
l 这样的函数都可以在不同的编译单元中被调用,只要在调用之前进行引用性声明(即声明函数原型)即可。也可以在声明函数原型或定义函数时用extern修饰,其效果与不加修饰的默认状态是一样的。
将变量和函数限制在编译单元内
l 使用匿名的命名空间:在匿名命名空间中定义的变量和函数,都不会暴露给其它的编译单元。
namespace { //匿名的命名空间
int n;
void f() {
n++;
}
}
l 这里被“namespace { …… }”括起的区域都属于匿名的命名空间。
标准C++库
l 标准C++类库是一个极为灵活并可扩展的可重用软件模块的集合。标准C++类与组件在逻辑上分为6种类型:
n 输入/输出类
n 容器类与抽象数据类型
n 存储管理类
n 算法
n 错误处理
n 运行环境支持
编译预处理
l #include 包含指令
n 将一个源文件嵌入到当前源文件中该点处。
n #include<文件名>
– 按标准方式搜索,文件位于C++系统目录的include子目录下
n #include"文件名"
– 首先在当前目录中搜索,若没有,再按标准方式搜索。
l #define 宏定义指令
n 定义符号常量,很多情况下已被const定义语句取代。
n 定义带参数宏,已被内联函数取代。
l #undef
n 删除由#define定义的宏,使之不再起作用。
条件编译指令——#if 和 #endif
#if 常量表达式
//当“ 常量表达式”非零时编译
程序正文
#endif
......
条件编译指令——#else
#if 常量表达式
程序正文1 //当“ 常量表达式”非零时编译
#else
程序正文2 //当“ 常量表达式”为零时编译
#endif
条件编译指令——#elif
#if 常量表达式1
程序正文1 //当“ 常量表达式1”非零时编译
#elif 常量表达式2
程序正文2 //当“ 常量表达式2”非零时编译
#else
程序正文3 //其他情况下编译
#endif
条件编译指令
#ifdef 标识符
程序段1
#else
程序段2
#endif
l 如果“标识符”经#defined定义过,且未经undef删除,则编译程序段1;
l 否则编译程序段2。
#ifndef 标识符
程序段1
#else
程序段2
#endif
l 如果“标识符”未被定义过,则编译程序段1;
l 否则编译程序段2。