C++中头文件和类的实例的大小之间的关系
2007-09-16 07:33
211 查看
在C++中为类编写头文件的时候,总是需要#include一大堆头文件。这两天认真的研究过后发现其中的大部分都是不需要的。
C++编辑器需要做的事情其实很简单1:扫描符号2:确定对象的大小。稍后你就会发现,为了确定这两件事情并不一定需要#include你用到的其他类的头文件。而只需要一个类型申明而已.
1.使用到类型的引用。首先我们知道对象的引用不是对象本身而是类似指针一样的东西。所以任何类型的对象的引用所占有的空间都是相同的。所以这里为了确定类型对象的大小,并不需要#include所使用到的类型的定义。
举例如下:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#ifndef SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#define SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class Sample
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
virtual ~Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private :
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
string& mSampleName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#endif /*SAMPLE_H_*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
这段代码会产生一个编译错误.具体的原因就是 找不到string这个类型。那么如何解决呢?我以前一般都是#include <string> using namespace std;其实这里不需要 因为mSampleName是一个string的引用而已.
只需要前向声明一下她是一个类型就可以了。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#ifndef SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#define SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class string;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class Sample
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
virtual ~Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private :
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
string& mSampleName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#endif /*SAMPLE_H_*/
注意新添加的那一行,这样就可以了。
2.使用类型的指针
和上面的例子一样,指针的大小总是可以确定的。所以也不需要#include头文件。只需要前向声明就可以了。
3.在成员函数的参数中使用的类型
无论类型是什么都只需要使用前向声明,因为成员函数几乎是不占对象的大小的。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#ifndef SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#define SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class string;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class IEnvelope;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class Sample
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
virtual ~Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
IEnvelope GetEnvelope();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
bool QueryEnvelope(IEnvelope& pEnv);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private :
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
string& mSampleName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#endif /*SAMPLE_H_*/
在写这段代码的时候我的project中根本就没有IEnvelope这个类型。所以其实根本没有IEnvelope.h可以#include。但是使用前向声明就可以让代码编译过去。这是因为成员函数不占用对象大小的原因。
总之在头文件里面如果你认为即使不能确定所使用到的某个类型的大小还是可以确定当前类型的对象的大小的时候就可以不用#include所使用到的类型的头文件。只需要前向声明一下就可以了。前向声明的作用在于告诉编译器这个一个在别的地方定义的类型。这样C++编译器就能生成正确的符号表了。
C++编辑器需要做的事情其实很简单1:扫描符号2:确定对象的大小。稍后你就会发现,为了确定这两件事情并不一定需要#include你用到的其他类的头文件。而只需要一个类型申明而已.
1.使用到类型的引用。首先我们知道对象的引用不是对象本身而是类似指针一样的东西。所以任何类型的对象的引用所占有的空间都是相同的。所以这里为了确定类型对象的大小,并不需要#include所使用到的类型的定义。
举例如下:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#ifndef SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#define SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class Sample
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
virtual ~Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private :
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
string& mSampleName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#endif /*SAMPLE_H_*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
这段代码会产生一个编译错误.具体的原因就是 找不到string这个类型。那么如何解决呢?我以前一般都是#include <string> using namespace std;其实这里不需要 因为mSampleName是一个string的引用而已.
只需要前向声明一下她是一个类型就可以了。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#ifndef SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#define SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class string;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class Sample
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
virtual ~Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private :
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
string& mSampleName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#endif /*SAMPLE_H_*/
注意新添加的那一行,这样就可以了。
2.使用类型的指针
和上面的例子一样,指针的大小总是可以确定的。所以也不需要#include头文件。只需要前向声明就可以了。
3.在成员函数的参数中使用的类型
无论类型是什么都只需要使用前向声明,因为成员函数几乎是不占对象的大小的。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#ifndef SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#define SAMPLE_H_
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class string;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class IEnvelope;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
class Sample
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
virtual ~Sample();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
IEnvelope GetEnvelope();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
bool QueryEnvelope(IEnvelope& pEnv);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private :
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
string& mSampleName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#endif /*SAMPLE_H_*/
在写这段代码的时候我的project中根本就没有IEnvelope这个类型。所以其实根本没有IEnvelope.h可以#include。但是使用前向声明就可以让代码编译过去。这是因为成员函数不占用对象大小的原因。
总之在头文件里面如果你认为即使不能确定所使用到的某个类型的大小还是可以确定当前类型的对象的大小的时候就可以不用#include所使用到的类型的头文件。只需要前向声明一下就可以了。前向声明的作用在于告诉编译器这个一个在别的地方定义的类型。这样C++编译器就能生成正确的符号表了。
相关文章推荐
- C++头文件和类实例的大小之间的关系
- STM32中flash大小-hex文件大小-bin文件大小之间的关系
- 关于ld -Ttext中的大小与text段在elf文件中的偏移之间的关系的猜想!
- c++将文件之间编译关系降到最低
- C++中基类和派生类之间的转换实例教程
- 用flex生成C++的文件实例分析
- Configure,Makefile.am, Makefile.in, Makefile文件之间关系(转)
- Oracle数据库、实例、用户、表空间、表之间的关系
- 为什么二进制文件与文本文件存入同样的数据,文件大小差异会这么大?(from <<Thinking in C++>>'s execise)
- opencv读取彩色/灰度图片像素值并存储在本地文件中c++代码实例及运行结果
- c++判断文件是否存在,判断是文件还是目录,获取文件大小,获取程序所在路径
- 图像大小,分辨率与人眼主观感受之间的关系 (与压缩编码无关)
- C/C++多种方法获取文件大小
- Linux中的文件描述符与打开文件之间的关系
- 成员变量、实例变量、属性之间的关系
- c++ - 为什么空类实例大小不是0
- spring05配置文件之间的关系
- 一个C++程序上传文件到百度云的实例
- Oracle - 数据库的实例、表空间、用户、表之间关系
- Configure,Makefile.am, Makefile.in, Makefile文件之间关系