C++编程技巧减少编译时间

1. #define的保护

所有头文件都应该使用#define 防止头文件被多重包含(multiple inclusion),命名格式

当是:<PROJECT>_<PATH>_<FILE>_H_

为保证唯一性,头文件的命名应基于其所在项目源代码树的全路径。例如,项目foo 中的头

文件foo/src/bar/baz.h 按如下方式保护:

#ifndef FOO_BAR_BAZ_H_

#define FOO_BAR_BAZ_H_

...

#endif // FOO_BAR_BAZ_H_

2. 头文件依赖

使用前置声明(forward declarations)尽量减少.h 文件中#include 的数量。

当一个头文件被包含的同时也引入了一项新的依赖(dependency),只要该头文件被修改,

代码就要重新编译。如果你的头文件包含了其他头文件,这些头文件的任何改变也将导致那

些包含了你的头文件的代码重新编译。因此,我们宁可尽量少包含头文件,尤其是那些包含

在其他头文件中的。

使用前置声明可以显著减少需要包含的头文件数量。举例说明:头文件中用到类File,但不

需要访问File 的声明,则头文件中只需前置声明class File;无需#include

"file/base/file.h"。

在头文件如何做到使用类Foo 而无需访问类的定义?

1) 将数据成员类型声明为Foo *或Foo &;

2) 参数、返回值类型为Foo 的函数只是声明(但不定义实现);

3) 静态数据成员的类型可以被声明为Foo,因为静态数据成员的定义在类定义之外。

另一方面,如果你的类是Foo 的子类,或者含有类型为Foo 的非静态数据成员,则必须为

之包含头文件。

有时,使用指针成员(pointer members,如果是scoped_ptr 更好)替代对象成员(object

members)的确更有意义。然而,这样的做法会降低代码可读性及执行效率。如果仅仅为

了少包含头文件,还是不要这样替代的好。

当然,.cc 文件无论如何都需要所使用类的定义部分,自然也就会包含若干头文件。

译者注:能依赖声明的就不要依赖定义。

以上是Google中C++编程规范的前两条要求。第一条相信大家都知道。第二条就是我要说的问题了。

这里我用VS2012解释下这个事情。要减少编译的目的就是要减少#include;

那我们先定义这样两个类:

#pragma once
class A
{
public:
	A(void);
	~A(void);
};
#pragma once
#include "A.h"
class B
{
public:
	B(void);
	~B(void);
private:
	A a;
};

可以看到这是很简单的组合类的情况。B类中有个A的对象。下面我们生成一下。

这时候A,B第一次编译成功

接下来我们修改对象A,在对象A中增加一个私有成员i,B不变;

#pragma once
class A
{
public:
	A(void);
	~A(void);
private:
	int i;
};

这时候再生成一次,可以看到如下情况

可以看到A编译后。编译器发现B中导入了A.h然后又编译了一次B。

在工程量比较小的时候这么做是没关系的。但当你编译一次代码需要1分钟2分钟的时候。我们频繁的修改源码然后编译你会崩溃的是不是?

所以前置声明是一个可以选择的解决方案。

B的代码只要做如下修改,取消导入A.h在B.h中声明class A;

#pragma once
class A;
class B
{
public:
	B(void);
	~B(void);
private
	A* a;
};

我们同样在A没修改之前做一次编译。

同样我们在A中加入私有成员后再编译一次。

可以看到这里只编译了A.cpp文件。

这种原因就是其实是C++的声明与定义并未完全分离的缘故。像Java就不会有这种问题=。=

时间: 2024-10-21 01:17:45

C++编程技巧减少编译时间的相关文章

C++编程技巧降低编译时间

1. #define的保护 全部头文件都应该使用#define 防止头文件被多重包括(multiple inclusion).命名格式 当是:<PROJECT>_<PATH>_<FILE>_H_ 为保证唯一性,头文件的命名应基于其所在项目源码树的全路径.比如,项目foo 中的头 文件foo/src/bar/baz.h 按例如以下方式保护: #ifndef FOO_BAR_BAZ_H_ #define FOO_BAR_BAZ_H_ ... #endif // FOO_BA

减少C++代码编译时间的方法

c++ 的代码包含头文件和实现文件两部分, 头文件一般是提供给别人(也叫客户)使用的, 但是一旦头文件发生改变,不管多小的变化,所有引用他的文件就必须重新编译,编译就要花时间,假如你做的工程比较大(比如二次封装chrome这类的开发),重新编译一次的时间就会浪费上班的大部分时间,这样干了一天挺累的, 但是你的老板说你没有产出,结果你被fired, 是不是很怨啊, 如果你早点看到这段文章,你就会比你的同事开发效率高那么一些,那样被fired就不会是你了,你说这篇文章是不是价值千金!开个玩笑 :),

单片机应用编程技巧问答

1. C语言和汇编语言在开发单片机时各有哪些优缺点? 答:汇编语言是一种用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言.其主要优点是占用资源少.程序执行效率高.但是不同的CPU,其汇编语言可能有所差异,所以不易移植. C语言是一种结构化的高级语言.其优点是可读性好,移植容易,是普遍使用的一种计算机语言.缺点是占用资源较多,执行效率没有汇编高. 对于目前普遍使用的RISC架构的8bit MCU来说,其内部ROM.RAM.STACK等资源都有限,如果使用C语言编写,一条C语言指令编译

减少编译时源文件之间的依赖

描述 在大型项目开发中,往往编译时间非常长,我见过需要编译15分钟的项目,这对于开发人员来说无疑是无奈的等待.如果每次一个小的代码修改,整个项目都要重新编译的话,时间成本是非常高,为了说明这个问题,下面举一个例子: 如下类: A.hpp class A { public: void foo(); private: AMember m_member; } 如果该头文件被包含在预编译头文件中,若修改类A,每个.cpp源文件都需要重新编译,因为A.h被预编译头文件包含,所有.cpp可能都需要类A.当我

VC/MFC 编程技巧大总结

1 toolbar默认位图左上角那个点的颜色是透明色,不喜欢的话可以自己改. 2 VC++中 WM_QUERYENDSESSION WM_ENDSESSION 为系统关机消息. 3 Java学习书推荐:<java编程思想> 4 在VC下执行DOS命令 a. system("md c:\\12"); b. WinExec("Cmd.exe /C md c:\\12", SW_HIDE); c. ShellExecute ShellExecute(NULL,

VC++DUIEngine界面编程1--学习编译及配置DUIEngine项目

1. 为什么要用DUIEngine: DUIEngine的作者是:启程软件.在此感谢他为此项目所付出的心血,能为我们这些界面爱好者,奉献了宝贵的时间以及优秀的代码. DUIE的优势为: 1. 作者将金山的BKWin进行了深度改写,从而使之更易于使用和开发.相比传统的WTL而言,DUIE增加了许多窗口特效,如动态缩放窗口,3D界面旋转.从而使开发者能够在较短时间内开发出比较炫丽的界面特效. 2. 结合了MFC及WTL开发者的开发习惯,使开发者能够在较短时间内接受DUIE的开发模式. 3. 作者长时

15个提高编程技巧的JavaScript工具

原文地址:http://www.imooc.com/wenda/detail/243523 JavaScript脚本库是一个预先用JavaScript语言写好的库,它方便了我们开发基于JavaScript的应用程序,特别适合AJAX和其他一些以Web为中心的技术.JavaScript主要用于编写嵌入或者包含在HTML页面的函数,从而实现DOM之间的交互. 这篇文章收集了15个可用于提高编程技巧的JavaScript工具,助你轻松快速完成工作.下面的这些JavaScript工具能让你管理Javas

JDBC编程之预编译SQL与防注入式攻击以及PreparedStatement的使用教程

在JDBC编程中,常用Statement.PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程. 1.Statement       该对象用于执行静态的 SQL 语句,并且返回执行结果. 此处的SQL语句必须是完整的,有明确的数据指示.查的是哪条记录?改的是哪条记录?都要指示清楚.     通过调用

ZStack中的编程技巧

1. 像函数一样使用的宏 //这个宏,用来被其他宏使用,构造一个正确有效的表达式.这个适合于一些离散语句的组合,不适合函数的重新命名 #define st(x)      do { x } while (__LINE__ == -1) 例如:#define aps_GroupsRemaingCapacity() ( APS_MAX_GROUPS - aps_CountAllGroups() ) 上述的这个宏,调用的其他函数来实现其功能,因此,不适合使用st()宏. 使用场景:  aps_Grou