zoukankan      html  css  js  c++  java
  • 理解extern

    extern有两层含义:表示声明和extern C


     1、C++分为编译期和运行期,C++是分别单独编译,编译期可认为有三个步骤:a、预编译进行文本替换,将源文件(cpp文件)生成编译单元;b、编译单元经过编译生成目标文件(obj文件);c、所有目标文件连接生成库(dll文件)或者可执行文件(exe文件)。

    2、在每个编译单元中,要使用一个对象,有两种方式:

      a、在当前把它定义出来

      b、告诉编译器,我有这个东西,但是它被定义在其他的编译单元,等到连接时找到它。这就是extern的第一个用法。

    3、extern修饰对象,说明只是声明,对象定义在其他地方,连接的时候找到他。可以编译通过,但是,你引用的对象必须确实在其他的编译单元中,并且个对象必须允许你引用,否则连接出错。

    4、考虑下面的需求,在一个编译单元内,我定义的对象,只想我自己使用,不给别人引用,该怎么办?

      a、使用static修饰,表示内链接,不让别人连接。

      b、使用匿名空间,虽然还是外连接,但是由于在匿名空间内,别人想连接也连接不上。

    5、C++对象是一次定义,多次声明。这是有例外的。

      a、考虑一次定义,首先确认一点,在一个编译单元内,不能重复定义。这也就是#ifndef/#define/#endif的作用

      b、对于不同的编译单元之间,允许重复定义。包括下列情况:

        static对象,const对象(没有extern),类定义,枚举定义,内联方法。

      c、考虑,为什么这些情况,允许在不同编译单元重复定义,也就是内链接。  

        对于类定义和枚举定义,在编译单元编译的时候,必须知道对象占用多大内存,只有声明是不够的,必须知道定义。

        对于内联方法,编译时进行文本替换,光有声明,没法替换。

        对于static,const(没有extern),每人都有自己的一份,彼此没有关系。

      e、考虑多次声明,对于类的成员方法和静态字段是不能重复声明的。


     1、C语言没有重载,没有异常,没有模版。对于重载,C++编译器会进行名称重整,而C语言不会。那么问题来了,考虑C/C++混合编程,比如C++调用C语言的方法实现,编译时没错。C编译器生成还是原来的方法名,C++编译器对方法名重整,连接时名称对不上,连接出错。当然C调用C++的方法实现也是同样的道理。

    2、该怎么解决这个问题?

      问题的关键是,C++编译器进行了名称重整,而C编译器没有。要能相互调用,必须告诉C++编译器不要重整名称,还使用原来的名称。这就是要使用extern C

    3、接口通过头文件体现,也就是同一份头文件。那么问题来了,对于C++编译器必须使用extern C,禁止名称重整。对于C编译器不认识extern C,不能有extern C,否则编译错误。该怎么办?

    4、使用预编译,对于C++编译器有extern C {},对于C编译器没有extern C {},如下:

    #ifdef _cplusplus

    extern C

    {

    #endif

    ...

    ...

    ...

    #ifdef _cplusplus

    }

    #endif

  • 相关阅读:
    layui的table中日期格式转换
    动态数据网站
    卷积的微分以及积分性质
    傅里叶变换时域积分性质
    矩阵导数的一些笔记
    3层模式下长时间调用的进度条提示方案
    有限区域内的孤立点(极点,有限阶0点)数量有限。
    关于复变函数积分--原函数法
    android 获取文本框回车输入
    企业网络搭建
  • 原文地址:https://www.cnblogs.com/nzbbody/p/3574271.html
Copyright © 2011-2022 走看看