当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

解析C++中的内部连接与外部连接

    在说内部连接与外部连接前,先说明一些概念。

      1.声明

      一个声明将一个名称引入一个作用域;

      在c++中,在一个作用域中重复一个声明是合法的


      以下都是声明:

    int foo(int,int); //函数前置声明

    typedef int Int; //typedef 声明

    class bar; //类前置声明

    extern int g_var; //外部引用声明

    class bar; //类前置声明

    typedef int Int; //typedef 声明

    extern int g_var; //外部引用声明

    friend test; //友员声明

    using std::cout; //名字空间引用声明

    friend test; //友员声明

    using std::cout; //名字空间引用声明

    int foo(int,int); //函数前置声明

      在同一个作用域中你可以多次重复这些声明。

      有两种声明不能重复,那就是类成员函数及静态数据成员的声明

    class foo
    {
     static int i;
     static int i;//不可以
     public:
      int foo();
      int foo();//不可以
    };

    2.定义

      一个定义提供一个实体(类型、实例、函数)在一个作用域的唯一描述。

      在同一作用域中不可重复定义一个实体。

      以下都是定义。

    int y;

    class foo ;

    struct bar ;

    foo* p;

    static int i;

    enum Color;

    const double PI = 3.1415;

    union Rep;

    void test(int p) {};

    foo a;

    bar b;

      3.编译单元

      当一个c或cpp文件在编译时,预处理器首先递归包含头文件,形成一个含有所有必要信息的单个源文件,这个源文件就是一个编译单元。这个编译单元会被编译成为一个与cpp文件名同名的目标文件(.o或是.obj)。连接程序把不同编译单元中产生的符号联系起来,构成一个可执行程序。

      4.自由函数

      如果一个函数是自由函数,那么这个函数不是类的成员函数,也不是友元函数。

      下面来看内部连接和外部连接

      内部连接:如果一个名称对于它的编译单元来说是局部的,并且在连接时不会与其它编译单元中的同样的名称相冲突,那么这个名称有内部连接(注:有时也将声明看作是无连接的,这里我们统一看成是内部连接的)。

      以下情况有内部连接:

      a)所有的声明

      b)名字空间(包括全局名字空间)中的静态自由函数、静态友元函数、静态变量的定义

      c)enum定义

      d)inline函数定义(包括自由函数和非自由函数)

      e)类的定义

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

      g)union的定义

      外部连接:在一个多文件程序中,如果一个名称在连接时可以和其它编译单元交互,那么这个名称就有外部连接。

      以下情况有外部连接:

      a)类非inline函数总有外部连接。包括类成员函数和类静态成员函数

      b)类静态成员变量总有外部连接。

      c)名字空间(包括全局名字空间)中非静态自由函数、非静态友元函数及非静态变量

      下面举例说明:

      a)声明、enum定义、union定义有内部连接

      所有的声明、enum定义及union定义在编译后不会产生连接符号,也就是在不同编译单元中有相同名称的声明及enum、union定义并不会在连接时发生发现多个符号的错误。

    // main.cpp

    typedef int Int; //typedef 声明,内部连接

    enum Color; //enum定义,内部连接

    union X //union定义,内部连接
    {
     long a;
     char b[10];
    };

    int main(void)
    {
    Int i = red;
    return i;
    }

    // a.cpp

    typedef int Int; //在a.cpp中重声明一个int类型别名,在连接时不会发生错误
    enum Color; //在a.cpp中重定义了一个enum Color,在连接时不会发生错误
    const Int i =blue; //const常量定义,内部连接
    union X //union定义,内部连接
    {
     long a;
     char b[10];
    };

      b)名字空间中静态自由函数、静态友元函数、静态变量、const常量定义有内部连接

    // main.cpp

    namespace test
    {
     int foo(); //函数声明,内部连接
     static int i = 0; //名字空间静态变量定义,内部连接
     static int foo() { return 0;} //名字空间静态函数定义,内部连接
    }

    static int i = 0; //全局静态变量定义,内部连接
    static int foo() {return 1;} //全局静态函数定义,内部连接
    const int k = 0; //全局const常量定义,内部连接
    int main(void)
    {
     return 0;
    }

    //a.cpp

    namespace test
    {
     int i = 0; //名字空间变量定义,外部连接
     int foo() {return 0;} //名字空间函数定义,外部连接
    }

    int i = 0; //全局变量定义,外部连接
    int k = 0; //全局变量定义,外部连接
    int foo() { return 2;} //全局函数定义,外部连接

  

共2页 首页 上一页 1 2 下一页 尾页 跳转到
相关内容
赞助商链接