| 订阅 | 在线投稿
分享
 
 
 

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

来源:互联网网民  宽屏版  评论
2008-06-01 01:48:00

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

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{RED,GREEN,BLUE};

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{red}; //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{blue}; //在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;} //全局函数定义,外部连接

在全局名字空间中,main.cpp中定义了静态变量i,常量k,及静态自由函数foo等,这些都有内部连接。假如你将这些变量或函数的static或是const修饰符去掉,在连接时就会现multiply defined symbols错误,它们与a.cpp中的全局变量、全局函数发生冲突。

QQ病毒

腾讯QQ空间代码专题

PPT教程专题

ADSL应用面面俱到

Fireworks教程专题

计算机和网络技术基础知识

校园网专题

网吧技术专题

 
特别声明:以上内容(如有图片或视频亦包括在内)为网络用户发布,本站仅提供信息存储服务。
 
  在说内部连接与外部连接前,先说明一些概念。   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{RED,GREEN,BLUE}; 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{red}; //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{blue}; //在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;} //全局函数定义,外部连接   在全局名字空间中,main.cpp中定义了静态变量i,常量k,及静态自由函数foo等,这些都有内部连接。假如你将这些变量或函数的static或是const修饰符去掉,在连接时就会现multiply defined symbols错误,它们与a.cpp中的全局变量、全局函数发生冲突。 QQ病毒 腾讯QQ空间代码专题 PPT教程专题 ADSL应用面面俱到 Fireworks教程专题 计算机和网络技术基础知识 校园网专题 网吧技术专题
󰈣󰈤
 
 
 
>>返回首页<<
 
 热帖排行
 
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
©2005- 王朝网络 版权所有