一文读懂C++ extern 链接属性 头文件的要点和关系

  • extern关键字

    • 一般用法:由于在C++中全局变量可以被定义在函数外面的任何地方。当我们想在某行使用全局变量时,如果当前文件的该行前找不到该全局变量的定义,那就必须在前面使用extern声明这个变量才可以使用该全局变量(extern声明只针对全局变量,不能使用在局部变量)。
    • 举例:
    extern int a;
    extern int b;
    int maxbb(int l,int r) {
        return l > r ? l : r;
    }
    int main() {
        cout << maxbb(a, b) << endl;
    }
    
    int a = 10;
    int b = 20;
    
    • 理解:就如同我们使用某个前面没有定义的函数一样,只有前面声明了该函数,编译器才知道该如何执行。用exter声明全局变量其实同理,就是让编译器知道这个是全局变量,以及它的类型。

    • 补充:

      • 像函数声明一样,我们也经常用extern声明全局变量,并将它们放到.h头文件中(我们知道一个.cpp文件include一个头文件,在编译时会把include这一句源封不动的直接替换成头文件中的内容)。这样就可以在不同的文件中定义或者使用这个全局变量了(看上面这个例子,是放在.cpp文件中的,这样的话所有使用这个全局变量的文件都要写一遍extern int a;extern int b;这两句声明,相当麻烦,这些都是和函数声明一样的道理)。
      • extern还有一个不太被关注的作用是,它可以改变const变量的链接属性。
  • 链接属性

    • C/C++代码的编译通常经过预编译,汇编,编译,链接。通常变量会有三种链接属性:外部链接,内部链接或无链接。具有函数作用域,块作用域或者函数原型作用域的变量都是无链接变量;具有文件作用域的变量可以是内部链接也可以是外部链接。而外部链接变量可以在多个文件中使用,内部链接变量只能在一个编译单元中使用(一个源代码文件和它包含的头文件)。
    • 简单的来说,只要不是文件作用域的变量,基本是无链接属性。而用const修饰的全局变量或者static修饰的变量拥有内部链接属性,它们只在当前文件中有效,对其他文件来说是不可见的。其他一般的全局变量拥有外部链接属性,可以被其他文件引用和访问。而用extern修饰const全局变量后(指的是在定义const全局变量时就用extern修饰,这是拥有外部链接属性的全局变量无需做的),就能将它的链接属性从内部链接改为外部链接,有趣的是,在C中,const全局变量默认是外部链接属性,而在C++中需要extern额外修饰。
  • 头文件

    • C++头文件中到底可以放什么,没有一个确定的答案,不同的项目和编程风格可能有不同的做法。但是,一般来说,有以下几个原则。

      • 头文件中应该只放变量和函数的声明,而不能放它们的定义。因为定义只能有一次,如果多个源文件包含了相同的定义,会导致多重定义的错误。
      • 头文件中可以写const对象的定义。因为全局的const对象默认内部链接,所以它只在当前文件中有效。把这样的对象写进头文件中,即使它被包含到其他多个.cpp文件中,这个对象也都只在包含它的那个文件中有效,对其他文件来说是不可见的,所以便不会导致多重定义。
      • 头文件中可以写内联函数(inline)的定义。因为内联函数会在编译时展开,而不是在链接时调用,所以不会产生多重定义的错误。
      • 头文件中可以写类(class)的定义。因为类的定义本质上是声明了类的成员变量和成员函数,而不是分配了内存空间。
      • 头文件中可以写模板(template)的定义。因为模板需要在编译时根据实际参数类型生成对应的代码,所以不能分离到源文件中。
    • 头文件中应该尽量避免重复包含(include)。为了防止一个头文件被多次插入到单个 .cpp 文件中,可以使用预处理指令(#ifndef, #define, #endif)(称为防卫式声明)或者#pragma once来保证头文件只被包含一次。值得注意的是,这样做可以保证的是在同一个编译单元中(一个cpp文件加上这个文件的所有头文件就是一个编译单元),一个头文件只被包含一次。若是不同cpp文件都包含了同一个头文件,这个头文件仍然会被多次包含(但这种多次包含正是头文件存在的意义,头文件就是为了复用声明代码)。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值