前言

本文总结了c++中前置声明的写法及注意事项,列举了哪些情况可以用前置声明来降低编译依赖。

前置声明的概念

前置声明:(forward declaration), 跟普通的声明一样,就是个声明, 没有定义。之所以叫前置声明,看下面一小段代码:

class Useful;  // 对Userful类的前置声明

class Boss
{
Useful *userful_; // 实际要用到它的地方
};

因为是在使用这个类型Userful之前告诉编译器,“哎,小编,Userful是个类,我要用它,你别管,它在某个地方是个真实的存在(也可能不存在,我就tm忽悠你的), 总之你不要管,我要用它”。这样跟编译器打过招呼之后,就能保证代码编译通过。Useful是在Boss使用它之前声明的,所以叫它前置声明。

作为一名c/c++程序员,合理使用前置声明可以使我们的生活更美好。因为它省去了#include的处理、降低文件之间的编译依赖,从而避免不必要的编译时间浪费。

利用前置声明的利弊

优点:避免#include, 避免修改一个被包含的头文件,导致整个文件重新编译。

缺点:(摘自Google)

  • 如果前置声明关系到模板,typedefs, 默认参数和 using 声明,就很难决定它的具体样子了。

  • 很难判断什么时候该用前置声明,什么时候该用 #includes, 特别是涉及隐式转换运算符的时候。极端情况下,用前置声明代替 includes 甚至都会暗暗地改变代码的含义。

  • 前置声明了不少来自头文件的 symbol 时,就会比单单 includes 一行冗长。

  • 前置声明函数或模板有时会害得头文件开发者难以轻易变动其 API. 就像扩大形参类型,加个自带默认参数的模板形参等等。

  • 前置声明来自命名空间 std:: 的 symbol 时,其行为未定义。

  • 仅仅为了能前置声明而重构代码(比如用指针成员代替对象成员),后者会变慢且复杂起来。

  • 还没有实践证实前置声明的优越性。

前置声明包含的类型

  • class(struct)
  • function
  • template
  • typedef

可以使用前置声明的情形

1、以指针或引用的形式来引用类型

class A;
class B
{
A *pa;//ok
A &ra;//ok A * f(const A * pa);//ok
A & f(const A & pa);//ok };

2、友元

class A;
class B
{
friend A; //ok
friend class A;//ok };

3、typedef

class C
{
public:
typedef int Aint;
};
class D
{
C::Aint * a_ ; //ok VC6.0 Qt都支持
};

4、做返回值或者参数

class A;
class B
{
void f(A a);//ok A g();//ok
};

不可以使用前置声明的情形

1、使用完整的类来引用

class A;
class B
{
//A a; //error };

2、被当做父类

class E;
class F: public E //error VC6.0--'E': base class undefined Qt5.6-invalid use of incomplete of 'class C'
{};

前置声明与作用域

1、in namespace

namespace somewhere
{
class G;
}
class H
{
somewhere::G * pa_; //OK
};

2、in class

#include<vector>
using namespace std;
//...
namespace ns1
{
class K
{
typedef vector<int> IntArray;
};
}
class L
{
void f(const ns1::K::IntArray & ary); //ok
};

C++类型前置声明的更多相关文章

  1. C++前置声明

    [1]一般的前置函数声明 见过最多的前置函数声明,基本格式代码如下: #include <iostream> using namespace std; void fun(char ch, ...

  2. C语言的不完整类型和前置声明(转)

    声明与定义(Declaration and Definition) 开始这篇文章之前,我们先弄懂变量的declaration和definition的区别,即变量的声明和定义的区别. 一般情况下,我们这 ...

  3. C++ 类的前置声明

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

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

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

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

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

  6. C++_前置声明

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

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

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

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

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

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

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

随机推荐

  1. DUBBO功能使用说明

    DUBBO功能使用说明 1 DUBBO概述 DUBBO是阿里巴巴公司的一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案. 相比于其他服务框架,DUBBO有如 ...

  2. android学习之--网格视图(GridView)和图像切换器(ImageSwitcher)

             GridView用于在界面上按行.列分布显示多个组件.GridView和ListView有共同父类:AbsListView. GridView与ListView的差别在于:ListV ...

  3. 京东云擎提供了免费的wordpress一键安装功能了

    1. 京东云擎(http://jae.jd.com)提供了免费的个人博客WordPress一键安装功能了,如下图,给开发者分享福利! 免费的应用,提供了源码,提供了数据库: 我之前把文章发到首页,遭到 ...

  4. Python 爬虫知识点 - 淘宝商品检索结果抓包分析

    一.抓包基础 在淘宝上搜索“Python机器学习”之后,试图抓取书名.作者.图片.价格.地址.出版社.书店等信息,查看源码发现html-body中没有这些信息,分析脚本发现,数据存储在了g_page_ ...

  5. GIS-011-Cesium 使用 IIS设置

    .terrain Content-Type='application/octet-stream'

  6. U3D关于message的使用

    Message相关有3条指令: SendMessage ("函数名",参数,SendMessageOptions) //GameObject自身的Script BroadcastM ...

  7. delphi中Case语法的使用方法

    Case 语句If...Then…Else 语句适合选项较少的情况,如果有很多选项的话利用If 语句就比较麻烦,在这种情况下,Case 语句就容易多了.Case 语句的语法如下: case <表 ...

  8. OpenStack Cinder 与各种后端存储技术的集成叙述与实践

    先说下下loop设备 loop设备及losetup命令介绍 1. loop设备介绍 在类 UNIX 系统里,loop 设备是一种伪设备(pseudo-device),或者也可以说是仿真设备.它能使我们 ...

  9. 【linux系列】vi模式下查找和替换

    一.查找 1.查找命令 /pattern<Enter> :向下查找pattern匹配字符串 ?pattern<Enter> :向上查找匹配字符串 在使用了查找命令之后,使用如下 ...

  10. JS-【同页面多次调用】轮播特效封装-json传多个参数

    看着传那么一长串的参数神烦,继续深化!——json传参: html: <div class="scrollBanner"> <ul class="ban ...