一个由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;
}
};
那么这个类就能被使用了,因为跟类体一起定义的函数就是内部链接对象了。
当然,如果写成前面这样,就涉及到类的名字解析了,关于类的名字解析,我暂时不说,以后有机会再写。
分享到:
相关推荐
一、关于staticstatic 是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从 static 修饰符的产生原因、作用谈起,全面分析static 修饰符的实质。 static 的两大作用: 一、控制存储方式 static...
浅谈C++中的几个关键字static,const,inline.doc 浅谈C++中的几个关键字static,const,inline.doc
PHP面向对象之旅深入理解static变量与方法 PHP面向对象之旅深入理解static变量与方法
面向对象与Java实现(多态、static、fina
彦舜原创,CSDN首发:希望对你有所帮助,仅此而已。内容工整规范,是作者本人,逐句敲出来,同时也含有个人的一些独见。
二、static属性与非static属性还有一个最大的区别,所有的非static属性必须产生实例化对象之后才可以访问,但是static属性不受实例化对象的控制,也就是 说,在没有产生实例化对象的情况下依然可以使用static属性。 ...
外部变量和static内部变量的区别等C语言知识讲解。
13_Java面向对象_第5天(static、final、匿名对象、内部类、包、修饰符、代码块)_讲义
(对于C++中的class对象例外, class的对象实例如果不初始化, 则会自动调用默认构造函数, 不管是否是static类型) 特点: static局部变量的”记忆性”与生存期的”全局性” 所谓”记忆性”是指在两次函数调用时, 在...
static成员变量不属于对象的一部分,而是类的一部分,所以程序可以在还没有诞生任何对象的时候就处理此种成员变量.不要把static成员变量的初始化操作安排在类的构造函数中,因为构造函数可能一再被调用,而static...
Java程序员面试陷阱大全 ------------------------------- ... 注: 静态内部类(Inner Class)意味着1创建一个static内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象
PHP面向对象之旅深入理解static变量与方法共11页.pdf.zip
2)当我们建立一个inner class时,其对象就拥有了与外部类对象之间的一种关系,这是通过一个特殊的this reference形成的,当内部类的成员方法中访问某个变量/方法时,如果在该方法和内部类中都没有定义过这个变量,...
C++程序的生与死(构造函数和析构函数),C++中的四种对象(全局对象、局部对象、静态(static)对象、以new方式产生出来的局部对象),以及在C++中有四种方法可以产生一个对象(in stack、in heap、global、local ...
static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); static inline void HH...
面向对象基础-static关键字
先看下面的例子,它将告诉我们在JS世界中也有C#里的public , private ,及static等
马士兵面向对象this——static
java基础知识 1、作用域public,private,protected,以及不写时的...注: 静态内部类(Inner Class)意味着1创建一个static内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象
任何对象之前就可以访问它 例如 类中的 main 方法声明为 static 所以不用创建该类 的实例就可以由 Java 运行时的系统调用 main 方法 关键字 static 可应用于变量 方法 甚至不属于方法的一段代码块 声明静态类的对象...