#include和前置声明(forward declaration)
1.    当不需要调用类的实现时,包括constructor,copy constructor,assignment operator,member function,甚至是address-of operator时,就不用#include,只要forward declaration就可以了。
2.   当要用到类的上面那些“方法”时,就要#include
 
例子:
boy.h
#ifndef __BOY__H_
#define __BOY__H_
#include<string>
using namespace std;
 
class Boy {
private:
    string name;
    int age;
};
 
#endif
 
test1.h
#include<iostream>
 
class Boy;
class People {
    Boy getBoyInfo();
};
 
test2.h
#include<iostream>
#include "boy.h"
 
class Boy;
class People {
    Boy getBoyInfo();
};
一个采用前置声明,一个采用#include "boy.h"加入了Boy的定义。两种方法都能通过编译。但是test1.h 这种写法更好。如果boy.h 的private成员变量改变,比如变成 char *name; test1.h 不需要重新编译,而test2.h 就要重新编译,更糟的是如果test2.h 还与其他很多头文件有依赖关系,就会引发一连串的重新编译,花费极大的时间。可是事实上改变一下写法就可以省去很多功夫。所以能用前置声明代替#include 的时候,尽量用前置声明
有些情况不能用前置声明代替#include
 
比如test1.h改成
#include<iostream>
using namespace std;
 
class Boy;
class People {
public:
    Boy boy;
};
 
test.cpp:7:9: error: field ‘boy’ has incomplete type
     Boy boy;
         ^
会编译错误,因为Boy boy定义了一个Boy类型变量,编译器为boy分配内存空间的时候必须知道boy的大小,必须包含定义Boy类的boy.h文件。
这是可以采用指针来代替
#include<iostream>
using namespace std;
 
class Boy;
class People {
public:
    Boy *boy;
};
指针的大小是固定的。在32位机上是4字节,64位机上是8字节。这时编译Task1的时候不需要Boy的大小,所以和Boy的定义无关。
如果使用object reference 或 object point 可以完成任务,就不要用object
这样可以尽最大可能避免#include
为声明式和定义是提供不同的头文件
第一个原则应该是,如果可以不包含头文件,那就不要包含了。这时候前置声明可以解决问题。如果使用的仅仅是一个类的指针,没有使用这个类的具体对象(非指针),也没有访问到类的具体成员,那么前置声明就可以了。因为指针这一数据类型的大小是特定的,编译器可以获知。
  第二个原则应该是,尽量在CPP文件中包含头文件,而非在头文件中。假设类A的一个成员是是一个指向类B的指针,在类A的头文件中使用了类B的前置声明并编译成功,那么在A的实现中我们需要访问B的具体成员,因此需要包含头文件,那么我们应该在类A的实现部分(CPP文件)包含类B的头文件而非在声明部分(H文件)包含。 

#include和前置声明(forward declaration)的更多相关文章

  1. 正确使用#include和前置声明(forward declaration)

    http://blog.csdn.net/SpriteLW/article/details/965702

  2. 宋宝华: Linux内核编程广泛使用的前向声明(Forward Declaration)

    本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:宋宝华 来源: 微信公众号linux阅码场(id: linuxdev) 前向声明 编程定律 先强调一点:在一切可 ...

  3. 关于C++中的前置声明(附程序运行图)

    实验于华中农业大学逸夫楼2017.3.10 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的程序中,带注释的那行就是类B的前置说明.这是必须的,因为类A中 ...

  4. C++ 类声明 类前置声明范例

    转载自http://www.cnblogs.com/staring-hxs/p/3244251.html 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的 ...

  5. 【C++】类前置声明范例

    • 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的程序中,带注释的那行就是类B的前置说明.这是必须的,因为类A中用到了类B,而类B的声明出现在类A的后面 ...

  6. C++中前置声明介绍

    前置声明是指对类.函数.模板或者结构体进行声明,仅仅是声明,不包含相关具体的定义.在很多场合我们可以用前置声明来代替#include语句. 类的前置声明只是告诉编译器这是一个类型,但无法告知类型的大小 ...

  7. c++ 类前置声明【转】

    [转自 here] 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的程序中,带注释的那行就是类B的前置说明.这是必须的,因为类A中用到了类B,而类B的声明 ...

  8. forward declaration of class 错误

    在使用Qt的时候遇到这个错误,查了一下发现,是因为我没有正确的使用前置声明. #ifndef FIRSTPAGE_H #define FIRSTPAGE_H #include "ui_dia ...

  9. c++中的前置声明

    引用google c++编码规范: When you include a header file you introduce a dependency that will cause your cod ...

随机推荐

  1. Windows 08R2_AD图文详解

    目录 目录 软件环境 Active Directory域服务 AD的应用 创建ADDS域 使用Windows窗口来创建ADDS域控制器 使用Powershell来创建ADDS域控制器 检查ADDC域控 ...

  2. SQL语句:随机取3条不重复的记录

    随机取3条不重复的记录 [Access]select top 3 * from tablename order by rnd(id); [SqlServer]select top 3 * from t ...

  3. python赞乎--学习开发

  4. js设置cookies

    //写入cookies的方法 function setCookie(name, value, seconds) { seconds = seconds || 0; //seconds有值就直接赋值,没 ...

  5. js的浏览器判断方法

    使用navigator.userAgent来判断浏览器类型. 1.浏览器版本号函数: var br=navigator.userAgent.toLowerCase();   var browserVe ...

  6. 如何取消bootstrap浮动时的padding值

    在bootstrap框架中使用浮动时,可以对元素添加pull-left 或 pull-right 类来达到目的.但是框架会默认给该元素添加一个15px的左右padding. <div class ...

  7. FZU 2060 The Sum of Sub-matrices(状态压缩DP)

    The Sum of Sub-matrices Description Seen draw a big 3*n matrix , whose entries Ai,j are all integer ...

  8. hdu 1130How Many Trees?(卡特兰数)

    卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列. 以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名,其前几项为(从第零 ...

  9. js 中的深拷贝与浅拷贝

    在面试中经常会问到js的深拷贝和浅拷贝,也常常让我们手写,下面我们彻底搞懂js的深拷贝与浅拷贝. 在js中 Array 和 Object  这种引用类型的值,当把一个变量赋值给另一个变量时,这个值得副 ...

  10. js返回顶部小Demo

    <style> .divH { height: 1800px; } .divT { width: 50px; height: 50px; font-size: 18px; backgrou ...