头文件中长包含的内容:
1. 函数原型
2. 使用#define或const定义的符号常量
3. 结构声明
4. 类声明
5. 模板声明
6. 内联函数的定义
C++存储方式是通过存储持续性、作用域和链接性来描述的。
编译器将分配固定的内存块来存储静态存储持续性变量,这些变量在整个程序执行期间一直存在。
如果没有显式地初始化静态变量,编译器将把它设置为0。
在代码块外部声明的变量默认为静态变量(使用static限定符修饰的变量链接性为内部,否则为外部);
在代码块内部声明的变量默认为自动变量(使用static限定符修饰,使其变为静态变量,无链接性,作用域)。
使用关键字extern来声明以前定义过的外部变量。
相对于局部的自动变量,外部变量也称为全局变量。
在局部变量名前使用作用域解析运算符"::",表示使用其全局版本。
存储说明符:
auto(在C++11中不再是说明符)
register(寄存器存储的自动变量)
static
extern
thread_local(C++11新增)
mutable(被其修饰的变量所在的结构体(或类)变量即使是const,此变量也能被修改)
C-V限定符
const(const全局变量的链接性为内部)
若程序员希望某个常量的链接性为外部,则可以使用关键字extern来覆盖默认的内部链接性。
volatile(若不将变量声明为volatile,编译器会将变量存储在寄存器中,这样保证了程序在多次调用同一变量后变量值不会发生变化(可能被硬件修改或多个程序共享数据);
若将变量声明为volatile,编译器将不会进行这种优化)
函数的内存模型
所有函数的存储性都默认为静态的,链接性为外部的。
可以使用关键字extern和static来限定函数的链接性。
单定义规则规定在多文件程序中,只能有一个相同函数的定义;
但内联函数不受此限制(但C++要求一个函数的所有内联定义都必须相同),内联函数可以在程序的多个文件中重复定义。
编译器先在程序文件中搜索函数定义,之后再到库中搜索。
语言链接性
语言链接性为另一种形式的链接性。链接程序要求每个不同的函数都有不同的符号名。
在C++中,同一个名称可能对应多个函数,必须将这些函数解释成不同的符号名称。
C++编译器执行名称校正或名称修饰,为重载函数生成不同的符号名称。
C语言链接性与C++语言链接性存在差异,
如果要在C++中使用C库中的预编译函数,可以使用函数原型来指出要使用的约定:
extern "C" void spiff(int); //指出使用C库中的函数spiff()extern void spiff(int); //默认使用C++库extern "C++" void spiff(int);//使用C++库
动态分配
使用new运算符初始化:
1. 为内置的标量类型分配空间并初始化
int *pi = new int (6);int *pj = new double (6.666);
2. 初始化常规结构或数组(需要用大括号)
struct where { double x; double y; double z; }where* pi = new where { 28.1, 33,4, 52.1};//C++11int *pj = new int [3] { 1, 2, 3};//C++11
同样,列表也可用于单值初始化。
new失败时将引发异常std::bad_alloc。
new和new []运算符分别调用如下函数:
void* operator new(std::size_t);//void* 是空指针;std::size_t对应于合适的整型void* operator new [] (std::size_t);
这些函数称作分配函数(alloction function)。
new运算符的一种变体称为定位new运算符,使用前必须包含头文件new。
名称空间
使用关键字namespace创建名称空间,默认情况下,名称空间中声明的名称的链接性为外部。
名称空间允许嵌套。
可以给名称空间创建别名:
namespace mfc = my_favorite_city;//让mfc成为my_favorite_city的别名
未命名名称空间的链接性为内部。