static inline 内部链接外部链接的关系讨论

一个由inline引起的讨论

以下函数定义有问题么:

//function.h

Void hello(){

       Printf(“hello,world”);

}

 

一般人看起来肯定觉得不对,因为我们基本上只把函数定义放在cpp里面,然后定义一个.h声明一下,在使用的地方include 一下这个.h就Ok了。可是为什么要这样做呢?

换句话说,如果我们按上面的方法定义hello(在一个.h里面定义),然后在两个文件a.cpp和b.cpp里面同时include了它,然后我们编译的时候没错,链接的时候告诉我们hello被定义了两次,这是为什么呢?

我们要知道,你include一个文件的时候相当于把那个文件的内容copy到被include的地方了。所以如果我们有两个文件a.cpp和b.cpp,我们都include了那个hello.h,然后编译,就相当于在a.cpp和b.cpp里面都定义了一个hello,然后链接当然出错了。这是问题的本质

 

然而,如果把hello的前面加一个inline,也就是说,改成

//function.h

Inline Void hello(){

       Printf(“hello,world”);

}

然后再定义a.cpp和b.cpp,同时incldue hello.h,编译和链接都能正常。这又是为什么呢?只不过我们加了一个inline而已。

问题是的本质是inline表明一个函数是内部链接对象,所谓内部链接对象。为了说清楚内部链接对象,我不得不讲一个东西。

编译单元:

       在C或者CPP里面,一个编译单元指的是一个可以被编译的文件,在C或者CPP里面,只有.C和.CPP才能被编译的,其它的任何扩展名的文件都不能被编译,比如.h就不能被编译。一个可以被编译的文件就是一个编译单元。所谓内部链接对象,指的是一个同样的名字,如果出现在两个编译单元里面,它们却算不同的东西,则是内部链接对象,否则,如果出现在不同的编译单元的同样的名字算同样的东西,同,就是外部链接对象。

       上面的问题加了inline之后就解决了是因为inline函数是内部链接对象,不加inline则是外部链接对象。

       同样的问题是static,函数加了static的则是内部链接,不加就是外部链接。对于类的定义也一样,如果一个类的一个函数跟类的实体一起定义的,就是内部链接,否则算外部链接。

       比如:

//tt.h

#include<iostream>

using namespacestd;

 

class TT{

public:

       TT();

public:

       void hello();

};

 

TT::TT(){

       cout<<"TT"<<endl;

}

 

void TT::hello(){

       cout<<"Hello,worle"<<endl;

}

你这样写的话,这个类是完了,只能被include一次,否则链接出错,因为它没有加static,也没加inline,也就是它是外部链接对象了。如果你把它改成

//TT.h

#include<iostream>

using namespacestd;

 

class TT{

public:

       TT(){

              cout<<"TT"<<endl;

       }

 

       void hello(){

              cout<<"Hello,worle"<<endl;

       }

};

那么这个类就能被使用了,因为跟类体一起定义的函数就是内部链接对象了。

当然,如果写成前面这样,就涉及到类的名字解析了,关于类的名字解析,我暂时不说,以后有机会再写。

posted @ 2013-05-21 06:38  夜月神  阅读(441)  评论(0编辑  收藏  举报