为什么类的定义应当写在头文件中,从而被多个源文件包含?

比如myclass.h定义了一个类myclass(只定义类,不定义成员函数),
file1.cpp里#include "myclass.h",编译得到file1.obj;
file2.cpp里也#include "myclass.h",编译得到file2.obj;
那么把file1.obj和file2.obj(和运行库)连接起来生成可执行文件的时候,为什么不会有冲突呢?2个文件都包含了myclass类的定义。

答:

因为这遵守“单一定义规则”(One-Definition Rule, ODR)。根据此规则, 如果对同一个类的两个定义完全相同且出现在不同编译单位,会被当作同一个定义。
这里头文件分别被两个不同的编译单位(file1.cpp, file2.cpp)包含,满足ODR规则,会被当作同一个定义。 所以不会有冲突。
此外,模板和inline函数也适用此规则。
追问
类的定义在目标文件比如file1.obj里是怎么体现的呢?它产生目标代码吗?类的定义不是变量名,也不是函数名,那么在代码段、数据段或符号表里面应该都没有条目?
 还是说,类的定义只是让编译器识别下文的这个类名?而对目标文件没有任何体现?
回答
细节依赖于编译器的实现。
以g++为例,类的代码出现在包含类方法定义的编译单元,引用他的编译单元会在链接时寻找类代码。如果.h中在类定义大括号内直接定义了函数,
那么类代码会出现在每一个include这个.h的编译单元中。 以前者为例:
myclass.h:
class MyClass 
{  
   public: MyClass(int i);    
  void add();    
  int m;
 };

myclass.cpp:
#include "myclass.h"
 MyClass::MyClass(int i) 
{   
  this->m = i;    
  add();
 }
 void MyClass::add() 
{    
 this->m ++;
 }
file1.cpp:
#include "myclass.h"
 void f1() 
{    
 MyClass mc(10);
 }
file2.cpp:
#include "myclass.h" void f2() 
{   
  MyClass mc(20); 
}
main.cpp:
 int main() 
{     
 void f1();   
  void f2();    
  f1();  
  f2(); 
}
可见类代码在myclass.o, file1.o在类定义的帮助下,通过_ZN7MyClassC1Ei引用类方法代码。 
其它细节可以反汇编代码、看elf/pe等文件格式文档以及编译器源代码。
所谓的编译只编译cpp文件,.h文件不参与编译,头文件的作用就是告诉编译器,
有这个类,但是类的实现在其他位置,编译时,编译器不会去找类的实现,
链接时编译器才会去寻找这个类的实现。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值