头文件中常包含的内容:
- 函数原型
- 使用#define或const定义的符号常量
- 结构声明
- 类声明
- 模板声明
- 内联函数
不同的编译器名称修饰的方式可能不同,可能为同一个函数生成不同的修饰名称。名称的不同将使链接器无法将一个编译器生成的函数调用与另一个编译器生成的函数定义匹配。在链接编译模块时,请确保所有对象文件或库都是由同一个编译器生成的。如果有源代码,通常可以用自己的编译器重新编译源代码来消除链接错误。
存储持续性、作用域和链接性
C++使用不同的方案来存储数据:
- 自动存储持续性
- 静态存储持续性
- 线程存储持续性
- 动态存储持续性
作用域描述了名称在文件的多大范围内可见。链接性描述了名称如何在不同单元间共享。
在默认情况下,在函数中声明的函数参数和变量的存储持续性为自动,作用域为局部,没有链接性。
对于,静态存储持续性变量,编译器将分配固定的内存块来存储所有的静态变量,这些变量在整个程序执行期间一直存在。
外部链接性:可在其他文件中访问。
内部链接性:只能在当前文件中访问。
无链接性:只能在当前函数或代码块中访问。
int global = 1000; //链接性为外部的静态持续变量
static int one_file = 50;//链接性为内部的静态持续变量
int main()
{
...
}
void funct1(int n)
{
static int count = 0;//无链接性的静态持续变量
int llama = 0;
}
void funct2(int q)
{
...
}
变量只能有一次定义。C++提供两种变量声明,一种是定义声明,另一种是引用声明。
引用声明使用关键字extern,且不进行初始化;否则声明为定义,导致分配存储空间。
double up;//定义声明
extern int blem;//引用声明
extern char gr = 'z';//定义声明:进行了初始化
extern double warming;
void local()
{
double warming = 0.8;
cout << warming << endl;
cout << ::warming << endl;
}
作用域解析运算符(::)放在变量名前面时,该运算符表示使用变量的全局版本。
单定义原则
以下代码不可行,因为它违反了单定义规则:
//file 1
int errors = 20;
...
-------------------------------------------
//file 2
int errors = 10;
...
以下代码可行:
//file 1
int errors = 20;
...
-------------------------------------------
//file 2
static int errors = 10;
...
可使用外部变量在多文件程序的不同部分之间共享数据;可使用链接性为内部的静态变量在同一个文件中的多个函数之间共享数据。另外,如果将作用域为整个文件的变量变为静态的,就不必担心其名称与其他文件中的作用域为整个文件的变量发生冲突。
将static限定符用于在代码块中定义的变量,虽然该变量只在该代码块中可用,但它在该代码块不处于活动状态时仍然存在。因此在两次函数调用之间,静态局部变量的值将保持不变。
mutable
可以用它来指出,即使结构(或类)变量为const,其某个成员也可以被修改。
struct data
{
char name[30];
mutable int accesses;
...
};
const data veep = ...;
veep.accesses++;
在默认情况下全局变量的链接性为外部的,但const全局变量的链接性为内部的。
动态分配
关于定位new运算符,需要翻阅书籍寻找更详细的解释。它能够指定内存分配的位置。