当出现访问类的函数或者需要确定类大小的时候,才需要用头文件(使用其类定义)

  

http://blog.csdn.net/clever101/article/details/4751717

看到这个警告,我想你一定悟到了什么。下面我说说我的结论:类的前置声明和包含头文件的区别在于类的前置声明是告诉编译器有这种类型,但是它没有告诉编译器这种类型的大小、成员函数和数据成员,而包含头文件则是完全告诉了编译器这种类型到底是怎样的(包括大小和成员)。这下我们也明白了为何前置声明只能使用指针来进行,因为指针大小在编译器是确定的。上面正因为前置声明不能提供析构函数信息,所以编译器提醒我们:“CSymbol”类型的指针是没有调用析构函数。如何解决这个问题呢?在Layer.cpp加上#include "Symbol.h"就可以消除这个警告。

声明和包含头文件区别

http://cache.baiducontent.com/c?m=9d78d513d9d430aa4f9d96690c66c0176d43f4632bd6a0020edf843c98732a405012e6ac27530775a5d20c6216ae394b9b872103311450c68cbcff5ddccb85582d9f5345676cf55661a20de88b182a9b66d618feae6afaa7a06ccefbc5d3a815089600127af7a1d6051714bd3eac0970fef6c715404817ceeb6163ac5a7022982143b445b1e7643b108181871a139d&p=8b2a970e828211a05bef912c484bbb&newp=99759a46d4c615f349b6c7710f5e88231610db2151d1d61f2b888213&user=baidu&fm=sc&query=%C7%B0%CF%F2%C9%F9%C3%F7+%CD%B7%CE%C4%BC%FE%B0%FC%BA%AC&qid=&p1=2

(2012-01-24 16:54:12)

转载

标签:

杂谈

一、类嵌套的疑问

C++头文件重复包含实在是一个令人头痛的问题,假设我们有两个类A和B,分别定义在各自的头文件A.h和B.h中,但是在A中要用到B,B中也要用到A,但是这样的写法当然是错误的:

class B;

class A{

public:

B b;
};

class B{

public:

A a;
};

因为在A对象中要开辟一块属于B的空间,而B中又有A的空间,是一个逻辑错误,无法实现的,在这里我们只需要把其中的一个A类中的B类型成员改成指针形式 就可以避免这个无限延伸的怪圈了,为什么要更改A而不是B?因为就算你在B中做了类似的动作,也仍然会编译错误,表面上这仅仅上一个先后顺序的问题

为什么会这样呢?因为C++编译器自上而下编译源文件的时候,对每一个数据的定义,总是需要知道定义的数据类型的大小在预先声明语句class B;之后,编译器已经知道B是一个类,但是其中的数据却是未知的,因此B类型的大小也不知道这样就造成了编译失败,VC++6.0下会得到如下编译错误:

error C2079: 'b' uses undefined class 'B'

将A中的b更改为B指针类型之后,由于在特定的平台上,指针所占的空间是一定的(在Win32平台上是4字节),这样可以通过编译

二、不同头文件中的类的嵌套

在实际编程中,不同的类一般是放在不同的相互独立的头文件中的,这样两个类在相互引用时又会有不一样的问题,重复编译是问题出现的根本原因为了保证头文件 仅被编译一次,在C++中常用的办法是使用条件编译命令在头文件中我们常常会看到以下语句段(以VC++6.0自动生成的头文件为例):

#IFNDEF  TESTSTR

#define TESTSTR

//很多语句

#endif

意思是如果没有定义过这个宏,那么就定义它,然后执行直到#endif的所有语句如果下次在与要这段代码,由于已经定义了那个宏,因此重复的代码不会被再次执行这实在是一个巧妙而高效的办法在高版本的VC++上,还可以使用这个命令来代替以上的所有:

#pragma once

它的意思是,本文件内的代码只被使用一次

但是不要以为使用了这种机制就全部搞定了,比如在以下的代码中:

//文件A.h中的代码

#pragma once

#include "B.h"

class A{

public:

B* b;

};

//文件B.h中的代码

#pragma once

#include "A.h"

class B{

public:

A* a;

};

这里两者都使用了指针成员,因此嵌套本身不会有什么问题,在主函数面使用#include "A.h"之后,主要编译错误如下:

error C2501: 'A' : missing storage-class or type specifiers

仍然是类型不能找到的错误其实这里仍然需要声明分别添加声明之后,可以成功编译了代码形式如下:

//文件A.h中的代码

#pragma once

#include "B.h"

class B;

class A{

public:

B* b;

};

//文件B.h中的代码

#pragma once

#include "A.h"

class A;

class B{

public:

A* a;

};

这样至少可以说明,头文件包含代替不了声明,有的时候只能依靠声明来解决问题,我们还要思考一下,有了声明的时候头文件包含还是必要的吗?我们尝试去掉A.h和B.h中的#include行,发现没有出现新的错误那么究竟什么时候需要声明,什么时候需要头文件包含呢?

三、两点原则

头文件包含其实是一想很烦琐的工作,不但我们看着累,编译器编译的时候也很累,再加上头文件中常常出现的宏定义感觉各种宏定义的展开是非常耗时间的,远不如自定义函数来得速度我仅就不同头文件源文件间的句则结构问题提出两点原则,仅供参考:

第一个原则: 如果可以不包含头文件,那就不要包含,这时候声明可以解决问题,如果使用的仅仅是一个类的指针,没有使用这个类的具体对象(非指针),也没有访问到类的具体成员,那么声明就可以了,因为指针这一数据类型的大小是特定的,编译器可以获知.

第二个原则: 尽量在CPP文件中包含头文件,而非在头文件中假设类A的一个成员是是一个指类B的指针,在类A的头文件中使用了类B的声明并便宜成功,那么在A的实现中我们需要访问B的具体成员,因此需要包含头文件,那么我们应该在类A的实现部分(CPP文件)包含类B的头文件而非声明部分(H文件).

三、两点原则

头文件包含其实是一想很烦琐的工作,不但我们看着累,编译器编译的时候也很累,再加上头文件中常常出现的宏定义。感觉各种宏定义的展开是非 常耗时间的,远不如自定义函数来得速度。我仅就不同头文件、源文件间的句则结构问题提出两点原则,仅供参考:

第一个原则应该是,如果可以不包含头文件,那就不要包含了。这时候前置声明可以解决问题。如果使用的仅仅 是一个类的指针,没有使用这个类的具体对象(非指针),也没有访问到类的具体成员,那么前置声明就可以了。因为指针这一数据类型的大小是 特定的,编译器可以获知。

第 二个原则应该是,尽量在CPP文件中包含头文件,而非在头文件中。假设类A的一个成员是是一个指向类B的指针,在类A的头文件中使用了类 B的前置声明并便 宜成功,那么在A的实现中我们需要访问B的具体成员,因此需要包含头文件,那么我们应该在类A的实现部分(CPP文件)包含类B的头文件 而非声明部分(H 文件)。

转载于:https://www.cnblogs.com/jeanschen/p/3382481.html

ZT 头文件包含其实是一想很烦琐的工作 第一个原则应该是,如果可以不包含头文件...相关推荐

  1. 查找文件夹下所有文件名字_我的电脑如何快速查找文件,分分钟钟找到你想要的文件!...

    相信用过windows的同学都知道,文件管理器里面有一个查找文件的功能,但是这个功能不够强大,它只能根据文件名,或是文件的修改时间和大小找到文件,如何根据文件内容查找想要的文件呢?下边小编就跟大家分享 ...

  2. Python 自动化指南(繁琐工作自动化)第二版:十六、使用 CSV 文件和 JSON 数据

    原文:https://automatetheboringstuff.com/2e/chapter16/ 在第 15 章,你学习了如何从 PDF 和 Word 文档中提取文本.这些文件是二进制格式的,需 ...

  3. QT中PRO文件写法的详细介绍,很有用,很重要!

    在QT中,有一个工具qmake可以生成一个makefile文件,它是由.pro文件生成而来的,.pro文件的写法如下: 1. 注释 从"#"开始,到这一行结束. 2.模板变量告诉q ...

  4. 计算机中的文件资源组织方式是什么意思,Windows中的库是什么,以及如何使用它们来组织文件 | MOS86...

    库是最容易被误解的,也是Windows中最有用的功能之一.它们可以帮助用户有效地组织文件和文件夹.通过使用库,您可以构建一个系统,以便始终可以在几秒钟内找到所需内容.不仅如此,您还可以通过点击几下(或 ...

  5. 一个清华大学生几天猎头生活的感想---很有感触的一篇文章(zz)

    从来没有想过自己会加入这一行,从开始自己喜欢的专业通讯,到后来喜欢的管理,幻想过是专业高手,幻想过管理专家,却从来没有想过进入这一行,但真的在我 刚刚离开校园的时候发生了,短短几天,对这个行业有了一个 ...

  6. 一个清华大学生几天猎头生活的感想---很有感触的一篇文章

    ZZ一个清华大学生几天猎头生活的感想---很有感触的一篇文章 2008-03-23 03:38 从来没有想过自己会加入这一行,从开始自己喜欢的专业通讯,到后来喜欢的管理,幻想过是专业高手,幻想过管理专 ...

  7. 认识Makefile文件(什么作用,格式怎样,如何工作)

    以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除. 参考博客:Make 命令教程 - 阮一峰的网络日志 一.Makefile文件是什么 Makefile 文件描述了 Linux 系统下 ...

  8. 【Gazebo入门教程】第一讲 Gazebo的安装、UI界面、SDF文件介绍

    [Gazebo入门教程]第一讲 Gazebo的安装.UI界面.SDF文件介绍 文章目录 [Gazebo入门教程]第一讲 Gazebo的安装.UI界面.SDF文件介绍 一.Gazebo的简介与安装 1. ...

  9. 学习python需要什么基础-要学Python编程,需要什么样的基础呢?想找这方面工作...

    原标题:要学Python编程,需要什么样的基础呢?想找这方面工作 作为一个初学Python的新手,如何学好这门语言,肯定经常是一头雾水. 那么,学好这门编程语言的基础是什么呢? 第一步,就是马上到网站 ...

最新文章

  1. leetcode-55 跳跃游戏
  2. mac tomcat https
  3. 基于大数据审计的信息安全日志分析法
  4. linux常用命令之lsof 、netstat、ipcs、ldd
  5. 【微信开发】微信公众号开发 之 编辑模式使用
  6. 使用asp.net 2.0中的SqlBulkCopy类批量复制数据
  7. python数字处理技巧(1): 精度舍入、精确运算、格式化、进制数、大数打包解包、复数、NaN、分数
  8. 使用双栈实现一个队列
  9. win7双系统,暴力删除ubuntu后出现grub rescue解决
  10. 任意形状文本检测:Look More Than Once
  11. 分库分表学习总结(3)——深入理解分布式事务
  12. 关于exe应用程序做成Windows服务爬过的坑
  13. win10+乌班图双系统安装(详细)
  14. think-cell学习
  15. 计算机听录测试,电脑自带可以录音但是QQ语音检测不行
  16. 如何申请注册微软邮箱(支持海外apple ID注册)亲测
  17. 德蕾莎修女---一个伟大的人
  18. Genymotion无法连接网络的解决办法
  19. 对Rapidly-exploring Random Trees(RRT)路径规划方法的理解
  20. PostgreSQL 多维空间几何对象 相交、包含 高效率检索实践 - cube

热门文章

  1. 不要紧张,一切尽在掌握:应激源可控性的神经相关因素
  2. R语言同时3条曲线到一个画布
  3. F1,RECALL,TPR,FNR等指标计算
  4. 告别苹果,英特尔明天会更好
  5. python证书微软认证费用_微软认证有哪些?费用多少?
  6. Broadcast详解
  7. 用win10怎么练计算机一级,你真的懂Win10吗?升Win10后必做的9件事
  8. CMake设置MSVC工程MT/MTd/MD/MDd
  9. 启动此程序因为计算机丢失msvcr110,无法启动此程序因为计算机中丢失msvcr110怎么办?...
  10. iOS 应用退到管理后台 左上角图片未更新(或不显示)