C++程序文件链接

1.什么是转换单元
程序中的每个.cpp文件和它包含的所有头文件称为一个转换单元。
编译器处理每个转换单元,生成二进制对象文件,用扩展名.obj来标识。
链接器将对象文件组合起来,生成一个可执行文件,用扩展名.exe来标识。

2.作用域
使用{}来限定变量的作用域

内部作用域可以定义一个和外部作用域相同的名称,此时,内部作用域中定义的名称,将隐藏外部作用域中的名称,

若要访问外层作用域中的名称,可使用解析运算符::,解析运算符的介绍,可参考 C++范围解析运算符::的使用

int main()
{
const int limit =10;
std::cout<<"limit 1 is "<<limit<<std::endl;
{
const int limit = 5;
std::cout<<"limit 2 is "<<limit<<std::endl;
std::cout<<"limit 3 is "<<::limit<<std::endl;
}
std::cout<<"limit 4 is "<<limit<std::endl;
}

输出结果:
limit 1 is 10
limit 2 is 5
limit 3 is 10
limit 4 is 10

3.转换单元的全局名称属性linkage
每个转换单元中的全局名称,都有一个属性linkage,该属性指明该全局名称可以在程序代码的什么地方使用。
内部链接属性:该名称只能在同一转换单元的任何地方访问。比如全局const变量
外部链接属性:该名称除了在同一转换单元访问外,还可在其他的转换单元中访问。除了全局const变量,其他的全局名称都是外部链接属性的。

局部名称没有链接属性。

4.什么是“一个定义”规则
在所有的转换单元中,外部链接属性的全局名称,如变量、函数、类类型、枚举类型、模板都只能定义一次
内联函数除外,内联函数的定义必须出现在调用该函数的每个转换单元中。

内部链接属性的名称可以在多个转换单元中同时定义。

5.如何访问另一转换单元中定义的变量
对于函数来说,如果函数的调用和定义不在同一个转换单元,编译器会把这个函数调用标记为外部的,让链接程序去处理它。

对于变量来说,是不同的。必须使用extern关键字来声明该变量。表示该变量的定义在另一个转换单元中。

示例代码如下:

myextern.cpp
int limit = 15;

mymain.cpp
int main()
{
    extern int limit;
    std::cout<<"Extern limit is "<<limit<<std::endl;
    return 0;
}

由链接属性linkage的介绍,我们知道const变量是内部链接属性的,只能在转换单元内部访问。

而定义一个const变量,希望其他的转换单元都可以使用的情况是常见的,如圆周率PI,const double pi=3.14159265,

那么,怎么才能让const变量也具有外部链接属性呢。
我们只需要在定义const变量时,也加上extern关键字就可以了。

示例代码如下:

myextern.cpp
extern const double pi=3.14159265;

mymain.cpp
int main()
{
    extern const double pi;
    std::cout<<"Extern pi is "<<pi<<std::endl;
    return 0;
}

另外需要说明的是,extern变量声明的位置,决定了该外部变量的作用域。

参考资料:《C++入门经典 第三版》 pp.309-318

原文地址:https://www.cnblogs.com/shijingjing07/p/5533702.html