为什么头文件只声明不定义
Ⅰ c++头文件里只有函数声明没有函数定义为什么能运行怎样做自己的头文件
库文件的实现都在c++运行库里,可能是静态链接或者动态库
Ⅱ c语言 中 为什么不将全局变量的定义放在头文件中
首先要说明什么是全局变量,c语言中全局变量一般是指定义在函数体外的变量。全局变量按可访问性可分为外部变量和内部变量。
内部变量是指使用了static关键字修饰的全局变量,它的可访问范围(作用域)被限定在本源文件所在的链接文件模块中,不能被其它文件模块引用。反之没有被static关键字修饰的全局变量则是外部变量,其它文件模块可以通过extern关键字引用该全局变量并访问。
要说明的是全局变量无论是内部变量还是外部变量,的存储类别都是静态的,也就是放到静态内存区域中,它编译链接阶段就已经分配好了固定的内存。
搞清楚上面的内容,就很容易得出若把全局变量放在头文件会有哪些问题;
一 对内部变量来说,每个include该头文件的文件模块中都会单独为这个内部变量分配静态内存空间,这个空间是相对独立的,是一种空间浪费,同时还失去了全局变量访问一致性的特点,实在没有什么意义。如果这个头文件只被一个模块使用,对于这个文件模块来说应该没啥问题。
二 对外部变量来讲,这个头文件被多个文件模块include的情况下,链接过程会报错,因为符号冲突,所有include这个头文件的模块都会有这个全局符号。在这个头文件仅仅只被一个模块include的时候可以正常使用。
经上分析得出要避免全局变量定义在头文件中,因为当这个头文件被多方include的时候会产生一些不必要的麻烦,就这么多。
全局变量作用域范围较广,被错误修改后排查定位问题比较困难,若非必要尽少使用。
下面说一下比较好的方式就是全局变量只定义在实现文件(.c,.m)中,对内部变量没啥说的它只在文件模块内部使用,对外部变量可以在该模块头文件中使用extern关键字修饰一下,这样其它文件模块只要直接include该头文件就可以使用模块中的外部变量了。
Ⅲ linux下明明包含了函数声明的头文件,为什么还显示没有定义的参数
你编译的时候要把源文件也一起编译;
比如自己定义了个sum.cpp sum.h
在main.cpp中调用,实际上是main调用了sum的库,所以要确保这个库存在,因此sum.cpp是需要编译生成对应库的,如果不去指定就什么都没有
所以要这样 g++ main.cpp sum.cpp;
不能只编译main.cpp。
Ⅳ C++书上写的是不能把变量定义在头文件中,头文件只能用来声明,为什么MFC中把变量都定义在头文件中
那只是建议,并不是绝对的
通常情况头文件是只存放声明,而.cpp文件存放定义
但也有例外,比如模板类。
如果头文件中存放变量的定义,而其他多个cpp文件包含了这个头文件,可能会导致该变量被重复定义而出现链接错误
Ⅳ 为什么VC的头文件里面的函数只有声明却没有定义
定义是有的,有一些定义被编译成了二进制码了,在头文件中应该可以看到预处理把这些文件包含进去了,就像你要静态调用dll文件就要用预处理把lib文件包含进去一样,至于各个函数的功能,如果是纯运算的那就是编译器的制作者写的,如果是对文件读写,创建窗口,这些就是调用了API函数
Ⅵ C++调用类头文件为什么只需要include声明部分而不需要类的定义部分
你这个问题问得好。
这牵扯到C++语言从编写-->执行整个过程。一般来讲,开发一个C++程序需要经过以下几步
1. 编写代码,
2. 编译器进行编译,compile
3. 编译器进行连接。
4. 执行。
由于C++语言支持多文件工程。需要经过编译和连接的过程。
打个比方,你要建造一架飞机,需要发动机,机翼,机身,尾翼,起落架。你可以把这几个部分交给专门的厂商去制作,这就是编译过程。这么多零件交给你,你只需要组装起来就可以了,这就是连接过程。
编译器(比如VC)就是加工零件的工厂,通过编译器的源代码会变成目标文件,也就是零件,VC生成的是.obj文件。
连接器(比如VC下的link)就是组装工厂,它能把所有的零件组装成你需要的东西。
好了,搞懂了编译器和连接器,我们再来看头文件.h和实现文件.cpp的作用。
还是拿飞机举例子。机身和机翼是必须连接起来的,但是他们之间怎么连接呢?制作机翼的只会做机翼,制作机身的也只会制作机身。那么作为组装工厂的你就会提供给他们一份飞机的接口设计图,图纸里面详细描述了机翼和机身怎么连接,但并不描述机翼和机身应该怎么去制作。那些零件工厂拿到结构图纸以后,就知道了,原来机翼是被安放在机身的这个地方,嗯,而且规定了用铆钉(打个比方)连接。好了,我知道了。可以做了,作为机翼制造商,我不用关心机身是怎么做的,我只关心机翼的制作和与机身的接口。换到C++这边来,这个用来描述接口的设计图就是.h文件,也就是头文件。具体机翼的实现也就相当于.cpp文件了。
所以,在程序中只需要应用头文件,也就是只需要知道接口的设计图。等你根据接口设计图设计好了零件,交给组装工厂,组装工厂(也就是连接器)会把所有的零件(编译器编译.cpp生成的.obj)连接起来,这样飞机就可以翱翔天空了。
Ⅶ 既然预编译只是起一个声明的作用,为什么不在工程中每个c文件中包含所有的头文件呢这样不是很方便么
预编译的时候会把包含的头文件展开,即把头文件里面的内容展开在当前文件中,如果包含所有头文件,第一会很占空间,因为有些头文件里面的变量(比如有很大的数组或者什么的)在当前这个文件并没有用到;其次很耗时间,因为要一个个去展开;第三,撇开时间和空间消耗不说,可能会存在不同头文件中声明或者定义了同名变量,这样在编译的时候就会报错。但是你却很难找到错误,因为头文件里面的东西你看不见,其次还可能引起一个重复包含的问题,比如头文件A.h包含了B.h,你在当前.c文件中如果#include"A.h" 后又#include"B.h" 的时候就会报错了,因为你重复包含了,当然重复包含可以通过#ifdef#endif机制解决。但是你不能保证每个头文件中都做了这样的操作。
Ⅷ class 类名;为什么添加头文件不可以,只可以提前声明,是不是mfc架构有什么特别注意的地方!
在使用这个类之前必须包含头文件,这个头文件必须在定义类对象的类所在头文件里面,而不是cpp文件中包含,在第一个类中加了class 另一个类的名的情况下,必须在cpp文件中包含该类声明的头文件。
Ⅸ C语言里有时候头文件光是声明了函数却没有定义函数,为啥就能用那
头文件的函数的实现文件都在其他文件中,比如VC++就是在那些.LIB和.DLL文件中。这样可以把实现文件转化为LIB和DLL,就可以保护你的源代码。而只留出来头文件,给别人看,别人用头文件作为接口,调用LIB或者DLL中的函数。
Ⅹ 为什么头文件里已经包含了函数的声明,调用还要声明
定义只能有一次,而声明的次数不限。任何标识符在使用前至少要有声明,将声明放在头文件中,就可以在需要使用到标识符时随时把头文件包含进来即可。如果把定义放进头文件中,那每包含一次头文件,标识符就定义了一次,这样在多文件的编译连接时很容易出问题的。 包含其实就相当于把被包含文件的内容加入到其中,和用被包含文件中的内容替换掉对应的包含语句没有区别。使用头文件的好处就是免除了重复劳动的麻烦。 反正最终编译器都是把被包含文件的内容合并到一块才编译的。所以这样,LZ觉得运行时的调用跟调用任何一个函数有区别吗。