引用google c++编码规范:

When you include a header file you introduce a dependency that will cause your code to be recompiled whenever
the header file changes. If your header file includes other header files, any change to those files will cause any code
that includes your header to be recompiled. Therefore, we prefer to minimize includes, particularly includes of header
files in other header files.

include一个头文件,就多了一种依赖,当头文件发生变化时,需要重新编译,因此尽量少用include,尤其是在头文件中包含头文件的情况下。

前置声明:减少include;解决循环依赖的问题。

如下,两个类中互包含了类对象成员,产生循环依赖。

class Barney{ Fred x;  };

class Fred{ Barney y;};

在使用一个类之前,必须先定义该类。使用前置声明,在引用未定义的类之前,将该类的名字告诉编译器,使编译器知道那是一个类名。

注意:提供完整类定义之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象。

前置声明使用错误情况1、

class Fred;

class Barney{ Fred x;  //error C2079: “Barney::x”使用未定义的 class“Fred”  };

class Fred {  Barney y; };

前置声明使用错误情况2、

class Fred;
class Barney
{

public: void method(){ x->dosomething(); //error C2227: “->dosomething”的左边必须指向类/结构/联合/泛型类型 }
private: Fred *x;
};

class Fred
{
public: void dosomething(){};

private:  Barney *y;
};

解决的办法:

修改两个类的定义顺序,或者将method改为非内联函数。

class Fred;

class Barney

{

public:   void method();

private:     Fred *x;

};

class Fred

{

public:    void dosomething(){};

private:     Barney *y;

};

//改成非内联函数,在Fred完整定义后在给出函数定义,或者更改两个类定义的顺序。

void Barney::method() {  x->dosomething(); }

综上,使用前置声明可以解决循环包含的部分问题。另外要避免互相定义使用类对象的情况。

google编码规范在头文件中使用前置声明的注意事项:

How can we use a class Foo in a header file without access to its definition?

  • We can declare data members of type Foo* or Foo&.

  • We can declare (but not define) functions with arguments, and/or return values, of type Foo. (One exception is if an argument Foo or const Foo& has a non-explicit, one-argument constructor, in which case we need the full definition to support automatic type conversion.)

  • We can declare static data members of type Foo. This is because static data members are defined outsidethe class definition.

摘自c++ primer:

class Screen;

前置声明,也称前向声明(forward declaration)。在声明之后,定义之前,类Screen是个不完整类型(incomplete type),即已知Screen是一个类型,但是不知道包含哪些成员。

不完全类型只能以有限方式使用。不能定义该类型的对象。不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数。

关键,区分下声明和定义。

c++中的前置声明的更多相关文章

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

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

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

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

  3. C++中头文件相互包含与前置声明

    一.类嵌套的疑问 C++头文件重复包含实在是一个令人头痛的问题,前一段时间在做一个简单的数据结构演示程序的时候,不只一次的遇到这种问题.假设我们有两个类A和B,分别定义在各自的有文件A.h和B.h中, ...

  4. C++中前置声明的应用与陷阱

    前置声明的使用 有一定C++开发经验的朋友可能会遇到这样的场景:两个类A与B是强耦合关系,类A要引用B的对象,类B也要引用类A的对象.好的,不难,我的第一直觉让我写出这样的代码: // A.h #in ...

  5. 【原创】SystemVerilog中的typedef前置声明方式

    SystemVerilog中,为了是代码简洁.易记,允许用户根据个人需要使用typedef自定义数据类型名,常用的使用方法可参见"define和typedef区别".但是在Syst ...

  6. C++ 类的前置声明

    http://www.2cto.com/kf/201311/260705.html    今天在研究C++”接口与实现分离“的时候遇到了一个问题,看似很小,然后背后的东西确值得让人深思!感觉在学习的过 ...

  7. C++ 前置声明 和 包含头文件 如何选择

    假设有一个Date类 Date.h class Date { private: int year, month, day; }; 如果有个Task类的定义要用到Date类,有两种写法 其一 Task1 ...

  8. C++_前置声明

    为什么要有前置声明? eg: -定义一个类 class A,这个类里面使用了类B的对象b,然后定义了一个类B,里面也包含了一个类A的对象a,就成了这样: //a.h #include "b. ...

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

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

随机推荐

  1. 学习构建一个简单的wcf服务

    入门,构建第一个WCF程序 1.服务端 建立一个控制台应用程序作为Server,新建一个接口IData作为服务契约.这个契约接口一会儿也要放到Client端,这样双方才能遵循相同的标准.别忘了添加对 ...

  2. MT【103】二阶递推找规律

    评:如果直接找$a_n$的二阶递推式:$a_{n+2}-2\sqrt{2}a_{n+1}-a_n=0$有根号,不利于估计尾数.

  3. 学习Spring Boot:(十八)Spring Boot 中session共享

    前言 前面我们将 Redis 集成到工程中来了,现在需要用它来做点实事了.这次为了解决分布式系统中的 session 共享的问题,将 session 托管到 Redis. 正文 引入依赖 除了上篇文章 ...

  4. 'sudo'不是内部或外部命令,,,,的解决办法

    [说明] Windows系统从 Vista 版本开始加入了 UAC 机制,这导致没有足够权限的程序无法获取到一些关键资源.在 Linux 下我们可以使用 sudo 命令方便地提升当前程序的执行权限,但 ...

  5. CODE FESTIVAL 2017 qual A 题解

    补一发A的题解. A - Snuke's favorite YAKINIKU 题意: 输入字符串S,如果以YAKI开头输出Yes,否则输出No. #include<bits/stdc++.h&g ...

  6. eclipse java build path问题汇总

    背景:在项目开发过程中,很多应用都进行了模块划分,有的时候是jar包依赖,有的时候通过build path进行配置,搞清楚这部分有助于理解项目之间的关系. 1 tms项目开发 1.1 问题描述 项目结 ...

  7. Flink流处理操作符

    一.工程创建与准备 使用maven进行工程创建,且采用提供的flink-quickstart模版,便利很多.

  8. MySQL存储引擎对比

    MySQL存储引擎对比 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL的存储引擎 大家应该知道MySQL的存储引擎应该是表级别的概念,因为我们无法再创建databas ...

  9. 何凯文每日一句打卡||DAY4

  10. info replication

    主Redis设置值:redis-cli -h 192.168.18.121 -p 63800 -a tinywan123456 登陆从1:redis-cli -h 192.168.18.121 -p ...