声明 是将一个名称引入一个程序.
定义 提供了一个实体在程序中的唯一描述.
声明在单个作用域内可以重复多次(类成员除外),定义在一个给定的作用域内只能出现一次. 一个定义就是一个声明,除非:
当一个实现文件(.cpp ...)编译时,预处理器(CPP)首先递归的包含头文件,形成一个保含有所有必要信息的单个源文件. 这个源文件称为 编译单元.
内部连接 如果一个名称对于它的编译单元来说是局部的, 并且在连接的时候不可能与其它编译单元中的同样的名称相冲突,则这个名称具有内部连接.即具有内部连接的名称不会被带到目标文件中.
外部连接 在一个多文件程序中,如果一个名称在连接时可以和其他编译单元交互,那么这个名称就具有外部连接. 即具有外部连接的名称会引入到目标文件中,由连接程序进行处理.这种符号在整个程序中必须是惟一的.
具有内部连接的定义包括:
具有外部连接的定义包括:
声明本身不会将任何符合引入目标文件,所以声明都是内部连接的.
某些声明可以激活对一个外部连接定义的访问,也许我们会很随便的说这些声明具有外部连接,如:
      int f();
      extern int i;
      class Point { static int s_numPoints; ... }; /* 类静态数据成员声明具有外部连接, 该数据必须在另一个地方被定义,如: point.c int Point::s_numPoints; */
还有一些声明即不把什么符号引入目标文件,也不能用来激活对外部连接定义的访问,我们常常称这类声明具有内部连接,
      typedef int INT;
      class Point;
      struct Point;
把一个带有外部连接的定义放在 .h 文件中都会引起错误.由于类的声明和定义都是内部连接的,一般都放在 .h 文件中.
| 
 
1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
inline int x(){    return x();}int y(){    return y();} | 
模板特化 头文件中最好使用inline标记来消除重复定义(消除外部连接)
| 
 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
 | 
#pragma once#include <stdio.h>template <class T> class myTemplate{public:    void F1(T& x, T& y);    void F2(T& x, T& y);};template<>void inline myTemplate<int>::F1(int& x, int& y){    int t=x;    x=y;    y=t;}template<>void myTemplate<int>::F2(int& x, int& y){    int t=x;    x=y;    y=t;} | 
| 
 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
 | 
#include "test.h"int t2(){    int x = 0, y = 0;    myTemplate<int> obj;    obj.F1(x, y);    obj.F2(x, y);    return 0;} | 
| 
 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
 | 
#include "test.h"int t1(){    int x = 0, y = 0;    myTemplate<int> obj;    obj.F1(x, y);    obj.F2(x, y);    return 0;} | 
原文:http://blog.csdn.net/xie1xiao1jun/article/details/30126019