• C++ extern关键字


    extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。

    ①声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块或者其他模块中使用,记住它是一个声明不是定义!

    ②链接指定。当它与"C"一起连用时,如: extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,因为C++支持函数的重载。

    其他tips:

    与include相比,extern引用另一个文件的范围小,include可以引用另一个文件的全部内容。

    extern 函数声明
      如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。即下述两个函数声明没有明显的区别:
    extern int f(); 和int f();
      当然,这样的用处还是有的,就是在程序中取代include “*.h”来声明函数。关于这样做的原因和利弊可见下面的这个例子:“用extern修饰的全局变量”

    (1) 在test1.h中有下列声明:

    #ifndef TEST1H
    #define TEST1H  
    extern char g_str[]; // 声明全局变量g_str
    void fun1();
    #endif

      (2) 在test1.cpp中

    #include "test1.h"     
    char g_str[] = "123456"; // 定义全局变量g_str
    void fun1() {
    cout << g_str << endl; 
    }

        (3) 以上是test1模块, 它的编译和链接都可以通过,如果我们还有test2模块也想使用g_str,只需要在原文件中引用就可以了

    #include "test1.h"
    void fun2()   
    { 
      cout << g_str << endl;   
    }

            以上test1和test2可以同时编译连接通过,如果你感兴趣的话可以用ultraEdit打开test1.obj,你可以在里面找到"123456"这个字符串,但是你却不能在test2.obj里面找到,这是因为g_str是整个工程的全局变量,在内存中只存在一份,test2.obj这个编译单元不需要再有一份了,不然会在连接时报告重复定义这个错误!
    (4) 有些人喜欢把全局变量的声明和定义放在一起,这样可以防止忘记了定义,如把上面test1.h改为

    extern char g_str[] = "123456"; // 这个时候相当于没有extern
          然后把test1.cpp中的g_str的定义去掉,这个时候再编译连接test1和test2两个模块时,会报连接错误,这是因为你把全局变量g_str的定义放在了头文件之后,test1.cpp这个模块包含了test1.h所以定义了一次g_str,而test2.cpp也包含了test1.h所以再一次定义了g_str,这个时候连接器在连接test1和test2时发现两个g_str。如果你非要把g_str的定义放在test1.h中的话,那么就把test2的代码中#include "test1.h"去掉 换成:

    extern char g_str[];
    void fun2()
    {   cout
    << g_str << endl; }

            这个时候编译器就知道g_str是引自于外部的一个编译模块了,不会在本模块中再重复定义一个出来,这样做非常糟糕,因为你由于无法在test2.cpp中使用#include "test1.h",那么test1.h中声明的其他函数你也无法使用了,除非也用都用extern修饰,这样的话你光声明的函数就要一大串,而且头文件的作用就是要给外部提供接口使用的,所以 请记住, 只在头文件中做声明,真理总是这么简单.

  • 相关阅读:
    Python学习-第三天代码作业
    网络原理-1
    整理操作系统
    操作系统--开发语言--重点
    操作系统
    C#数组的声明方式
    string.Format对C#字符串格式化(转)
    C#中两个Form窗口之间的传值(父->子)(子->父) (转)
    opencv MatchTemplate()模板匹配寻找最匹配部分
    摄像头,图片筛选颜色
  • 原文地址:https://www.cnblogs.com/mathyk/p/10921612.html
Copyright © 2020-2023  润新知