zoukankan      html  css  js  c++  java
  • C++ 声明与定义

    一步一步讲起:

    1、C++程序生成可执行文件的过程:源文件(.cpp),经过预编译,生成编译单元;编译单元,经过编译,生成目标文件(.obj);目标文件,经过连接,生成可执行文件。

    2、预编译做的事情:对#include,#define进行文本替换。

    3、C++支持单独编译,也就是对每个编译单元进行单独编译。这就要求,编译单元是一个自包含的文件,也就是说,编译单元生成目标文件的时候,不需要其他的信息。因此,在编译单元内部,所有使用的东西,必须要有定义,或者有声明。定义的意思是:这个东西就放在这里,当然可以使用。声明的意思是:我有这个东西,但是这个东西放在其他地方,这样的话,就可以使用声明的东西了。

    4、可以多次声明,但只能一次定义(有例外)。为什么?

    我可以重复说,我有这个东西,我有这个东西。但是我不能把一个东西放在多个地方。

    5、声明只是说,我有这个东西,什么时候定位到这个东西呢?

    编译的时候,声明我有这个东西,就可以用了。在后面连接的时候,会从其他的目标文件,找到这个东西。

    6、可以多次声明,但只能一次定义,是有例外的。有些情况不能重复声明,那就是类的成员方法和静态数据成员。

    7、可以多次声明,但只能一次定义,是有例外的。有些情况是允许重复定义的。为什么允许重复定义?

    在编译单元中,在编译的时候,对于有些东西,可以说,我有这个东西,就可以使用,等到连接的时候,找到这个东西。但是对于有些东西,只有声明,说我有这个东西,是不行的,必须定义,才能使用。这样就出现了,在多个编译单元进行了重复定义。这样的情况有:

      a、加 static 前缀的全局变量定义.如: static int x;

      b、枚举类型的定义.如: enum Boolean {NO,YES };

      c、类的定义. 如: class Point { int d_x; int d_y; ... };

      d、内联函数的定义.如: inline int operator==(const Point& left,const Point&right) { ... }

      e、union的定义.

      f、名字空间中const常量定义

    为什么只有声明是不够的呢?

    这是因为编译的时候,只有这些信息是不够的,比如类,只有声明,是没法分配内存的,内联方法,只有声明,是没法展开进行文本替换的。

    8、那么问题来了,对于上面的情况,在多个编译单元,都进行了定义,连接的时候,为什么没有重定义的错误呢?

    这是因为,对于上面的情况,连接的时候,是内部链接的,也就是说,连接的时候,不到外面找相同的东西了。

    9、上面说的是,在多个编译单元之间,进行了重复定义,连接时不会报错,是因为内部连接。那么,在一个编译单元之内,进行了重复定义呢?会出现什么情况?

    答案是:编译错误。

    10、在一个编译单元内,不能进行重复定义。那么,问题又来了,在预处理的时候,#include递归地进行文本替换,这种时候,就会出现重复定义,如何解决呢?

    答案是:使用头文件保护符。

    #ifndef  XXX

      #define XXX

    #endif

    这样,就避免了重复地替换,也就不会出现重复定义了。注意,头文件保护符只是保证在一个编译单元,不会重复定义。在多个编译单元,还可能会重复定义。

    11、也就是说,在一个编译单元内,肯定不能重复定义,否则编译错误。在多个编译单元之间呢,对于内部连接的情况,允许重定义。对于外部连接的情况,不允许重复定义。

    12、在多个编译单元之间,为了避免出现重复定义,有两种解决办法:

      a、使用内部连接。

      b、使用外部连接,并且使用不具名空间。使用不具名空间,也是外部连接,为什么连接的时候,不会报错呢?

      这是因为,不具名空间,虽然是外部连接,但是可以认为不具名空间是个封装的东西,外部连接想连接也连接不到。推荐使用外部连接。

  • 相关阅读:
    【uva 1515】Pool construction(图论--网络流最小割 模型题)
    【uva 1617】Laptop(算法效率--贪心,2种理解)
    【uva 10570】Meeting with Aliens(算法效率--暴力+贪心)
    【uva 1153】Keep the Customer Satisfied(算法效率--贪心+优先队列)
    【uva 1615】Highway(算法效率--贪心 区间选点问题)
    Sublime PlantUML环境配置
    [转] 基于TINY4412的Andorid开发-------简单的LED灯控制
    洛谷P2606 [ZJOI2010]排列计数 组合数学+DP
    洛谷P3158 [CQOI2011]放棋子 组合数学+DP
    BZOJ2440/洛谷P4318 [中山市选2011]完全平方数 莫比乌斯函数
  • 原文地址:https://www.cnblogs.com/nzbbody/p/3366362.html
Copyright © 2011-2022 走看看