为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

内部链接与外部链接

2018-01-06 6页 doc 18KB 26阅读

用户头像

is_594905

暂无简介

举报
内部链接与外部链接内部链接与外部链接 首先,我们来了解下定义: 内部连接:如果一个名称对编译单元(.cpp)来说是局部的,在链接的时候其他的编译单元无法链接到它。 外部连接:如果一个名称对编译单元来说不是局部的,而在链接的时候其他的编译单元可以访问它,也就是说它可以和别的编译单元交互。 通过对LIB与DLL的讲解,我们可以更方便的理解内部连接与外部连接。 我们了解了一个编译单元(.cpp)编译成obj文件后,至少还会有未解决符号表、导出符号表、地址重定向表。而如果这个名称是内部连接的话,那在导出符号表中不存储它的入口。也就是别的obj...
内部链接与外部链接
内部链接与外部链接 首先,我们来了解下定义: 内部连接:如果一个名称对编译单元(.cpp)来说是局部的,在链接的时候其他的编译单元无法链接到它。 外部连接:如果一个名称对编译单元来说不是局部的,而在链接的时候其他的编译单元可以访问它,也就是说它可以和别的编译单元交互。 通过对LIB与DLL的讲解,我们可以更方便的理解内部连接与外部连接。 我们了解了一个编译单元(.cpp)编译成obj文件后,至少还会有未解决符号表、导出符号表、地址重定向表。而如果这个名称是内部连接的话,那在导出符号表中不存储它的入口。也就是别的obj文件无法链接到这个名称。而外部连接刚好相反,在导出的符号表中有它入口。 以下情况有内部连接: a)所有的声明 b)名字空间(包括全局名字空间)中的静态自由函数、静态友元函数、静态变量的定义 c)enum定义 d)inline函数定义(包括自由函数和非自由函数) e)类的定义 f)名字空间中const常量定义 g)union的定义 以下情况是外部连接: a)非static全局变量与全局函数 b)类非inline函数总有外部连接。包括类成员函数和类静态成员函数 c)类静态成员变量总有外部连接 d)名字空间(包括全局名字空间)中非静态自由函数、非静态友元函数及非静态变量 好了,我们通过程序来深刻的理解吧: 假设有3文件: TestBase.h: TestRun.cpp TestError.cpp int a; #include "TestBase.h" #include "TestBase.h" 当然还有一个包含main()方法的Test.cpp输出的文件。 #include "TestBase.h" extern int a; void print() { cout << a<总结
了下3点必须: (1)。类中的static变量请不要在声明类中定义。一般我们类的声明是写到.h文件中,而实现写到对应的cpp文件中的,理由看程序。 还是刚才3个文件: TestBase.h: TestRun.cpp TestError.cpp class A #include "TestBase.h" #include "TestBase.h" { int A::getA() public: { void setA( int a ); return m_a; int getA(); } inline int getB(); void A::setA( int a ) private: { int m_a; m_a = a; static int m_b; } }; int A::m_b = 5; 编译都成功后,链接会出现如下信息: TestError.obj : error LNK2005: "private: static int A::m_b" (?m_b@A@@0HA) already defined in Test.obj TestRun.obj : error LNK2005: "private: static int A::m_b" (?m_b@A@@0HA) already defined in Test.obj Debug/Test.exe : fatal error LNK1169: one or more multiply defined symbols found 也就是说类中的static变量m_b为外部连接,理由同上面写的全局变量a一样。解决办法是 把int A::m_b = 5;写到类的实现文件TestRun.cpp 中,这样就只有TestRun.obj文件的导 出符号表中提供了m_b,而其他的obj文件如果需要的话,那这只能在它的未解决符号表中 存在了,它自然只能在TestRun.obj文件中找到m_b的入口,这样就无任何冲突了。所以类 中的static变量请一定不要在声明类中定义。 (2)。内中的非static函数请一定也不要在声明类实现,除非你的声明和实现是写到一起的。 TestBase.h: TestRun.cpp TestError.cpp class A #include "TestBase.h" #include "TestBase.h" { int A::getA() public: { void setA( int a ); return m_a; int getA(); } inline int getB(); int A::m_b = 6; private: int m_a; static int m_b; }; void A::setA( int a ) { m_a = a; } 编译通过,链接后肯定不能通过,原因都一样,就是因为类中的非static函数是外部链接。而如果你把定义和声明写到一起,那就没问,但你应该知道这样写就是相当于出卖了自己,你把你的实现代码都给了别人。 (3)inline函数请一定要在类的声明文件中实现。大家应该看到类中的inline函数我没有写它的实现代码,其实也就是为了这条定义一样。你可以查看VC提供的头文件中inline的定义与实现都是写在头文件中的。 所以那个inline函数你必须写在TestBase.h内。 inline int A::getB() { return m_b; } 为什么这样呢,因为inline函数是内部连接,它不在导出符号表。假如你把inline int getB() 的实现代码写在了 TestRun.cpp中,那链接后的错误信息是: Debug/Test.exe : fatal error LNK1120: 1 unresolved externals 也就是别的cpp文件就无法用到找到它了。 好了,其实很多东西如果是在链接时候出错了,或者为什么语法这么实现的,你可以从它是内部连接还是外部链接入手,你会发现很多规律以及规则的存在,这样你的编写的C++的代码安全性一定会大大的提高。相信我~
/
本文档为【内部链接与外部链接】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索