1分离编译
在构建多源文件的程序时,将会分离编译每个源文件 ( 作为编译单
元,可以并行编译,节约时间 ) ,得到多个独立的可重定位目标文件
(*.o) 。这些可重定位目标文件最终会被链接器链接成单个可执行文件
目标文件。命令:g++ -c
链接器使得分离编译成为可能。这样,开发者不用将一个大型程序组
织为一个巨大的单个物理模块 ( 例如,将所有代码都放到 main() 所在
的源文件 ) ,而是可以把它分解为若干个更小、更好管理的物理模
块,这样就可以独立地修改和编译这些物理模块。
当修改这些模块中的一个时,只需简单地重新编译修改模块并重
新链接所有模块 , 而不必重新编译其他文件。这使得构建时间大大
地减少!
2.名字解析
对象跨模块的定义与使用是允许分离编译的基础,它是通过链接器的
符号解析机制来实现的:
这需要在编译时,为分散在不同源文件中对象的使用名和定义名
生成相应的链接符号 ( 有符号名、地址、大小等信息 ) ,然后在链
接时,对这些符号进行相互关联解析。
这使得最终能够将对象的使用名关联到其定义名上,完成所谓的
名字解析。
链接时,链接器会将所有的外部符号关联到唯一的全局符号。
3.对象的链接性
3.1
链接性:描述对象的定义名允许与使用名进行关联的范围。
3.2
外部链接:对象的定义名允许所有文件中的使用名进行关联。
外部链接的对象可被整个程序多个源文件共享链接,成为全局对象。
编译时,对象的定义名被转换为存储地址,对象的使用名被转换成符号。
链接时,链接器会把某个目标文件中表示对象使用的符号关联到另一个目标
文件中对象定义所在存储区的存储地址 ( 如某个函数被编译后所对应的机器
指令代码片段的首地址 ) 。
3.3
内部链接:对象的定义名只允许定义名所在源文件的使用名进行关联。
内部链接的对象只在其定义文件中访问。
3.4
无链接:对象的使用名不需要链接到定义名,因为对象的使用名与定义名的关
联在编译时已经完成了。在某个块中创建 / 销毁的对象是无链接的,只属于这
个块,不能被共享,称为局部对象 / 局部变量。
4.示例
4.1内部链接
//如果在某个源文件中定义无名命名空间,则该无名命名空间只在该源文件能访问。 namespace { int i=0; int f(){ return 5; } }
//无法外部链接 #include <iostream> using std::cout; using std::cin; using std::endl; extern int i; extern int f(); int main(){ cout<<"i:"<<i<<endl; cout<<"f()"<<f()<<endl; }
4.2外部链接
int k=9; int g(){ return 6; } namespace m1{ int j=8; int p(){ return 3; } }
//实现外部链接 #include <iostream> using std::cout; using std::cin; using std::endl; extern int k; extern int g(); namespace m1{ extern int j; extern int p(); } //using namespace m1; using m1::j; using m1::p; int main(){ cout<<"k:"<<k<<endl; cout<<"g():"<<g()<<endl; cout<<"j:"<<j<<endl; cout<<"p():"<<p()<<endl; }
今天的文章
c++内部链接和外部链接的区别_c++字符串连接分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/80899.html