我最近在做一个抓包的程序,里面有自定义了很多的类。也用到了一些全局的变量,我的习惯是定义一个Globle.cpp,一个Globle.h.比如在Globle.cpp里面定义变量int a ,在Globle.h里声明为extern int a;然后在我其他文件需要的时候包含Globle.h,就可以用这个全局变量a了。这个办法以前一直用着没问题,但昨晚出问题了。
//我的Globle.h
#ifndef _GLOBLE_H_ //全局变量
#define _GLOBLE_H_
#include "pcap.h"
#include "remote-ext.h"
#pragma comment(lib, "wpcap.lib")//连接库extern  bool bisThreadquit; //声明为外部变量(不是定义),判断线程是否退出
extern  pcap_if_t *alldevs; //获得的网卡信息变量
// 自定义消息
#define WM_PDATABUF (WM_USER+101)  //发送数据包解析
struct ANI//这里这样定义就没错
{
CString str0;
CString str1;
CString str2;
};
struct Macname 
{
char* cname;
u_int u_netmask;
};//STRName[5];
struct Macname STRName[5];//!!!!!问题出在这儿
//static struct Macname STRName[5];//!!!!!问题出在这儿
#endif
   我定义一个全局的结构体数组Macname STRName[5],然后在其它文件包含了Globle.h,但是程序连接的时候硬说我重复定义了Macname STRName[5]这个数组,但是我除了在上面定义没有在其它地方定义的。
   检查了很久,最后加了个static,即static struct Macname STRName[5],就没问题了,但有人说这样我在其它文件里的
Macname STRName[5],不是唯一的一个Macname STRName[5],而是多个,但我断点调试发现确是唯一的一个(因为变量的值同一时刻都是相同的)。
  我现在彻底迷茫了,不知道开始我的问题出在了哪里,加了static后为什么又不报错了,求解。
  还有就是想问问大家在实际工程中如何处理全局变量的?
  谢谢,谢谢,谢谢!!!

解决方案 »

  1.   

    需要extern
    static具有文件可见性,即其它源文件不可见此变量,当然不会重定义了
      

  2.   

    static的作用域在编译单元有效,在“Globle.h”定义了一个static对象,其他模块include“Globle.h”的时候,编译器会分配一个只在该模块可见的static对象,在该模块对static对象的操作也只会改变自己模块的那个值,对其他引用模块没有影响。
     上面这个是我根据static变量的规则自己试验的结果
      

  3.   

    但是我用了extern ,程序还是有错啊,说我重复定义
    我是这样改的:
    //Globle.h
    extern  struct Macname STRName[5];
      

  4.   

    1、我的习惯是定义一个Globle.cpp,一个Globle.h.比如在Globle.cpp里面定义变量int a ,在Globle.h里声明为extern int a;然后在我其他文件需要的时候包含Globle.h,就可以用这个全局变量a了。这一点你比我强,我以前一直是每个cpp中加extern int a,后来才意识到可以加在h文件中。这个方法仍然是最好的办法。大家在实际工程中如何处理全局变量就是这样处理的。关键是h文件中必须有“extern”。2、struct Macname STRName[5];//!!!!!问题出在这儿Globle.h这样肯定不行的,如果Globle.h只被其它cpp文件包含一次是可以的。
    如果Globle.h只被n个其它cpp文件,就是重复定义,肯定不行。
    所以:极少有人在h文件中定义全局变量。3、静态变量的文件有效性2楼已经回答。
    所以可以在在h文件中定义静态变量,而且还比较常见。当然你也可以每个文件单独添加。
      

  5.   

    谢谢你哈,我明白了,受益匪浅。
    总结一句话:就是不要在h文件中定义全局变量!!!除了有特殊的3种情况。其余只能声明。另外我由此还有个小白问题。就是h文件我定义了结构体,
    struct Macname  
    {
    char* cname;
    u_int u_netmask;
    }STRName[5];
    用里面的char* cname时,一定要new吗?
    比如
    char *cword = "hello,world";
    strcpy(STRName[0].cname,cword);
    但是我记得也可以不 new啊!因为我印象中有这么个用法,具体也说不上来了。唉,最近脑壳打铁....
      

  6.   

    关于结构,要注意一点:3、构建(教材也称为定义,其实不妥当)一个结构Macname一般在Macname.h中进行,构建之后,Macname就int一样,是一个type了。(此时不是object)然后,假设在xxx.cpp再用Macname这个type去定义“变量”(此时一般称为“对象”,英语中的object,可以说变量是狭义的object,object的本质是编译后会占据内存的,有地址的):Macname mymacname;并且在xxx.h中 加入 extern Macname mymacname,就很方便使用了。实际上,这种自定义的type,完全适用上面的1、2两点。4、定义结构的类型Macname也可以在cpp中进行,如果只被该文档使用的话。5、定义了结构体用里面的char* cname时,不一定要new,但是struct Macname   
    {
    char cname[40];
    u_int u_netmask;
    }STRName[5];
    这种用法,用在某个cpp文件可以,不可以用在h文件。原因在于STRName[5]是定义object,就是上面第2点所说的。struct Macname   
    {
    char cname[40];
    u_int u_netmask;
    };放在h文件中是可以的。然后Macname STRName[5]要在cpp文件中进行。