欢迎来到天天文库
浏览记录
ID:30767102
大小:88.22 KB
页数:8页
时间:2019-01-03
《c++中声明与定义的区别(从链接角度分析)》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类的实现放在cpp文件屮。它们为什么能够关联到一起呢?你知道什么东西可以放在・h文件屮,什么不能。什么东西又可以放在cpp文件中。如果你忘记了或是压根就不明白,那么读过此文你会清晰无比!!首先谈卜•声明与定义的区别。声明是将一个名称引入程序。定义提供了一个实体在程序中的唯一描述。声明和定义有时是同时存在的。如inta;externintb=1;只有当extern中不存在初始化式是才是声明。其他情况既是定义也是声明。但是在下列情况下,声明仅仅是声明:1:仅仅提供函数原型。如voidfunc(int,int);2:e
2、xterninta;3:classA;4:typedef声明5:在类中定义的静态数据成员的声明如:[cpp]viewplaincopy1.classA2.{3.public:4.staticinta;〃声明。5.};[cpp]viewplaincopy1・classA2.{3.public:4.staticinta;//声明。5・};下列情况下,定义仅仅是定义:1:在类定义之外,定义并初始化一个静态数据成员。如A::a=0;2:在类外定义非内联成
3、员函数。声明仅仅是将一个符号引入到一个作用域。而定义提供了一个实体在程序中的唯一描述。在一个给定的定义域屮重复声明一个符号是可以的,但是却不能重复定义,否则将会引起编译错误。但是在类中的成员函数和静态数据成员却是例外,虽然在类内它们都是声明,但是也不能有多个。如:[cpp]viewplaincopy1.classA2.{3.public:4・statixinta;5・staticinta;6・voidfunc(int,int);7.voidfunc(int8.};[cpp]viewplaincopy1.4、panstyle=Hfont-size:18px;H>classA2.{3.public:4.staticinta;5・staticinta;1.voidfunc(int2.voidfunc(int^int);8・};明白了声明与定义的区别,还需要明白内部链接、外部链接。只有明白了它们你才会知道开头提出的问题。在编译时,编译器只检测程序语法和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以牛成冃标文件。而在链接程序时,链接器会在所有的訂标文件屮找寻函数的实现。如果找不到,那到就会报链接错误码(LinkerError)o在VC下,这种错误一般是:5、Link2001错误,意思说是说,链接器未能找到函数的实现。链接把不同编译单元产生的符号联系起来。有两种链接方式:内部链接和外部链接。如果一个符号名对于它的编译单元來说是局部的,并FL在链接时不可能与其他编译单元中的同样的名称相冲突,那个这个符号就是内部链接。内部链接意味着对此符号的访问仅限于当前的编译单元屮,对其他编译单元都是不可见的。static关键字作用在全局变量时,表示静态全局变量。但是作用域仅仅在当前文件作用域内。其他文件中即使使用extern声明也是无法使用的。const也类似。带冇static>const关键字和枚举类型的连接是内部的。具有内部链接的符号无法作用于6、当前文件外部,要让其彩响程序的其他部分,可以将其放在・h文件中。此时在所有包含此.h文件的源文件都有自己的定义且互不影响。类的定义具有内部链接,由于它是定义,因此在同一编译单元屮不能重复出现。如果需要在其他编译单元使用,类必须被定义在头文件且被其他文件包含。仅仅在其他文件屮使用classa;声明是不行的,原因就是类的定义是内部链接,不会在目标文件导出符号。也就不会被其他单元解析它们的未定义符号。理解这一点很重要。内联函数也具有内部链接。在一个多文件的程序中,如果一个符号在链接时可以和其他编译单元交互,那么这个名称就有外部链接。外部链接意味着该定义不仅仅局限在单个编译单元中。它可7、以在・o文件屮产生外部符号。可以被其他编译单元访问用来解析它们未定义的符号。因此它们在整个程序中必须是唯一的,否则将会导致重复定义。非内联成员函数、非内联函数、非静态自由函数都具有外部链接。内联函数Z所冇具冇内部链接,因为编译器在可能的时候,会将所冇对函数的调用替换为函数体,不将任何符号写入・o文件。判断-•个符号是内部链接还是外部链接的一个很好的方法就是看该符号是否被写入.0文件。前面说的是定义对链接方式的影响,接下来说下声明对链接方式的影响。由于声明只对当前编译单元有用,因此声明并不将任
4、panstyle=Hfont-size:18px;H>classA2.{3.public:4.staticinta;5・staticinta;1.voidfunc(int2.voidfunc(int^int);8・};明白了声明与定义的区别,还需要明白内部链接、外部链接。只有明白了它们你才会知道开头提出的问题。在编译时,编译器只检测程序语法和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以牛成冃标文件。而在链接程序时,链接器会在所有的訂标文件屮找寻函数的实现。如果找不到,那到就会报链接错误码(LinkerError)o在VC下,这种错误一般是:
5、Link2001错误,意思说是说,链接器未能找到函数的实现。链接把不同编译单元产生的符号联系起来。有两种链接方式:内部链接和外部链接。如果一个符号名对于它的编译单元來说是局部的,并FL在链接时不可能与其他编译单元中的同样的名称相冲突,那个这个符号就是内部链接。内部链接意味着对此符号的访问仅限于当前的编译单元屮,对其他编译单元都是不可见的。static关键字作用在全局变量时,表示静态全局变量。但是作用域仅仅在当前文件作用域内。其他文件中即使使用extern声明也是无法使用的。const也类似。带冇static>const关键字和枚举类型的连接是内部的。具有内部链接的符号无法作用于
6、当前文件外部,要让其彩响程序的其他部分,可以将其放在・h文件中。此时在所有包含此.h文件的源文件都有自己的定义且互不影响。类的定义具有内部链接,由于它是定义,因此在同一编译单元屮不能重复出现。如果需要在其他编译单元使用,类必须被定义在头文件且被其他文件包含。仅仅在其他文件屮使用classa;声明是不行的,原因就是类的定义是内部链接,不会在目标文件导出符号。也就不会被其他单元解析它们的未定义符号。理解这一点很重要。内联函数也具有内部链接。在一个多文件的程序中,如果一个符号在链接时可以和其他编译单元交互,那么这个名称就有外部链接。外部链接意味着该定义不仅仅局限在单个编译单元中。它可
7、以在・o文件屮产生外部符号。可以被其他编译单元访问用来解析它们未定义的符号。因此它们在整个程序中必须是唯一的,否则将会导致重复定义。非内联成员函数、非内联函数、非静态自由函数都具有外部链接。内联函数Z所冇具冇内部链接,因为编译器在可能的时候,会将所冇对函数的调用替换为函数体,不将任何符号写入・o文件。判断-•个符号是内部链接还是外部链接的一个很好的方法就是看该符号是否被写入.0文件。前面说的是定义对链接方式的影响,接下来说下声明对链接方式的影响。由于声明只对当前编译单元有用,因此声明并不将任
此文档下载收益归作者所有