为什么不要在头文件中写上函数定义?

为什么不要在头文件中写上函数定义?

在C++/C中,一般的函数与全局变量的申明都会放在.H文件中,而且会在相应的.C文件中对函数和变量进行定义.全局变量在头文件中前面要加上EXTERN,定义时则不用
如果你在.H文件中对函数或变量直接定义,这个头文件只被一个文件包含是不会出错的,但是一旦它被两个或更多的文件包含,则会报错.编译器会告诉你函数或变量重复定义!
你可能会说,我不是已经在头文件中加上了防止重复引用的措施了吗?
#ifndef...
#define...
函数或变量的定义..
 
        #endif    
实际上这种措施只能防止在一个文件中对头文件的重复引用:在一个文件中一个头文件被引用了一次之后,再次引用时会首先判断是否已被引用过,若是则跳过,这样就防止了头文件的重复引用.若有多个文件引用同一头文件,则会出错,例如:
 
//f.h
#ifndef _F1_H_
#define _F1_H_
int a;
#endif
//f1.cpp
#include "f1.h"
main()
{
cout<<a<<endl;
}
//f2.cpp
#include "f1.h"
void fun2()
{
cout<<a<<endl;
}
宏的作用域:宏的作用域只在一个文件中.
错误的原因是:f1.cpp首先引用了头文件,包含了a的定义,然后在f2.cpp中再次引用了f1.h,f1.h首先会进行判断是否定义了宏_F1_H_,因为宏的作用域没有超过一个文件的范围,所以判断的结果是_F1_H_没有被定义过--虽然f1.cpp中已经定义过一次,但是它是局部的!a在f2.cpp中再次被定义!
 
      看了这东西就让我想起了c++ primer plus 中的“单定义原则”,即函数的定义只可以有一次,所以呢,若果将定义都写在头文件,当1.cpp中include 了这个头文件,而2.cpp有include头文件,呢么编译时候就会发现有两个相同的函数定义,违反单定义原则,就会报错了。这就是今天我试着写一个类时候,调试的冒烟的犯的错误了。而且在试着写类是,也学习到一些东西(不要笑啊,我是初学者而已)
     1.局部值类型变量是必须初始化才能用的,如果定义的是全局变量,则没有赋值就会使用默认值,而引用类型的变量不管是全局的还是局部的都可以使用默认里面的默认值。所谓的默认值就是 int=0,bool=0,string=“”,char=空字符(“/0”)...经过测试的确符合,而且这所谓的全局,局部变量对于一般类型(int,double,bool。。)甚至类中的数据成员也是如此,只要是全局的变量,全局的类,呢么变量,类中的数据变量就会有默认值,只要是局部的类或者变量,就会没有默认值,没有初始化。
       查了原因如下:

【局部变量是在堆栈中分配,编译器通常不加入额外代码为局部变量指定默认值,这就会导致局部变量的初始值不确定。这在C/C++代码中表现的尤其明显。C#编译器同样不会为局部变量默认添加一段代码赋予默认值,这往往是从效率上考虑。因为很多代码中对变量只是先声明,然后才使用,如果声明时就复制,势必影响效率,所以编译器把这个控制权放手给了代码编写者。

比如下面例子

int a;

SetA(out a);

这个代码是可以编译通过的,但如果在申明时就对a赋值,显然是多此一举的,这样做只会导致程序执行效率的下降,所以编译器是不会默认给局部变量赋值。

另外局部变量的分配内存的速度很快,只是移动堆栈指针就搞定了,不需要实际分配内存,所以如果做赋值操作,在汇编级别你会发现会比分配内存还要消耗CPU,因为首先要将要赋的值拷贝到寄存器,然后再从寄存器复制到堆栈指针指定的内存地址中。

由于编译器为了效率没有对局部变量赋默认值,那么不对局部变量赋值就使用,将导致不可预料的结果,所以编译器给出错误让代码编写者改正。】

       
         以上就是我学习到的。有问题请指正。
 
guyue
2013—7—24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值