C++ 内连接与外连接
cpp源文件与h头文件关系
我们知道C++支持多种编程范式,可以完全用采用面向过程,不去用类,当然了很少有人这样做,一般是结合面向过程与面向对象.
那假如有一些处在不同源文件中的变量和函数(不是类中的变量成员或成员函数),我们要使用不同源文件中的变量或函数时咋整呢? 在面向对象中我们使用一个个类的时候自然是用头文件引用下就OK.但现在没有类,只是一个个变量和函数,也能用引用头文件吗 ? 这得看情况,有时可以,有时不行.如果头文件中只有外部声明没有任何定义,那引用头文件完全没有问题.如果头文件中有定义的话,如果只被一个cpp文件引用则没问题,如果被多个cpp文件引用就会出现重复定义的错误.(注:编译器是以cpp文件为单位编译,如果某个h头文件没有被引用的话相当于被抛弃不用了.引用头文件时预编译时只是简单的把头文件复制到引用它的cpp文件中.)
extern外部声明
假如在有one.cpp和two.cpp两个源文件.
//one.cpp中
---------------------------------------------------
#include <iostream>
using namespace std;
int number = 123; //number的定义
void Print() {cout<<"hi,i am one.cpp"<<endl;}
//two.cpp中
--------------------------------------------------------
#include <iostream>
using namespace std;
extern int number;//这就是所谓的外部声明,此处extern不可省
extern void Print(); //此处extern可以省略.
cout<<number; //结果为123
Print(); //输出i am one.cpp
在two.cpp中是怎么得到one.cpp中的number的值的呢,由于用extern int number这样声明了下,表明number在其他源文件中有定义,链接器就会帮助去其他源文件中找的.
假如把上面two.cpp中的extern关键字去掉. 编译时不会出错.但链接时出错了,重复定义了.因为one.cpp中已经定义了个number,不能再定义一个相同的了.
static 内部连接
上面的例子中我们知道one.cpp和two.cpp中同时写上int number会出错,说重复定义了.但如果这样
//one.cpp中
static int number = 123;
//two.cpp中
static int number; //没显式赋值,会默认赋予0
此时却不会出错.因为定义变量时默认是外部连接的.而加上关键字static表示是静态变量,是内部连接,链接器不会去看不同cpp编译成的obj文件中有重名的静态变量不.
当用static修饰后就不能再使用extern修饰了.
//one.cpp中
static int number = 123;
//two.cpp中
extern int number;
cout<<number;
此时会出错,因为extern声明的number找不到定义.因为one.cpp的number用static修饰表明是内连接了.
const关键字
//one.cpp中
const int number = 123;
//two.cpp中
const int number = 321;
这里达到的效果与static一样,都属于内部连接,所以不会出错.唯一不同的时const表示常量,定义时必须显式赋予值,且赋值后不能再改变它的值.
不过const还有另外一个特性就是可以和extern一起用.
比如在two.cpp中这样写
extern const int number; //
cout<<number; //输出的值是one.cpp中的number值123
inline与static函数也是内部连接的
//one.cpp中
void Test() { }
//two.cpp中
void Test() { }
这样编译时会报错,重复定义了.但如果把上面的两个void Test都改成inline void Test() { }或者static void Test() { }则不会出错.//注意这里讲的inline函数指的是全局函数,不是类里面的inline函数.
所以函数跟一般变量差不多.没任何修饰的就默认是外部连接,有static修饰的则是内部连接.另外没有const函数这一说,只有在类中才可以在函数后面加个const来修饰
补充:软件开发 , C++ ,