C++如何避免修改头文件时导致项目重新编译

前言:

我们都知道,在使用某个class或者struct的时候,需要包含这个class或者struct所在的头文件,以便成功编译。但是,如果在一个大型项目中,代码动辄几十万行,如果一旦修改头文件,就会导致包含该头文件的所有文件都要重新编译,这将耗费非常多的时间。那么,怎样才能尽可能防止重新编译呢?

在这里插入图片描述

正文:

   很多童鞋马上想到了使用增量编译。其实,对我们来说增量编译是基本的设置,因此我们这里假定已经使用了增量编译。那么还有什么方法可以做到吗?

   答案是,当然有了。

   我们在头文件中使用某个class的时候,如果不是使用对象而是使用指向对象的地址的指针,那么我们就可以轻松做到避免不必要的编译了。

   假定类型CMyClass是在他处定义的类,我们的代码如下:

// user.h

#include myclass.h // CMyClass所在的头文件

class CUser {

public:

public:

string getInfo(CMyClass& obj); // 此处用到了CMyClass

};

// user.cpp

#include “user.h”

string CUser::getInfo(CMyClass& obj) {

pObj->xxx();

}

在这里插入图片描述

在上述代码中,”user.h”中,因为接口getInfo使用CMyClass定义了对象,因此编译器必须知道该对象是什么样子,所以它要求我们包含myclass.h以便知道其具体定义。但是,一旦CMyClass的定义发生变化,那么user.h将被重新编译,这会导致所有包含user.h的文件都被重新编译。这是没有必要的,而且浪费编译时间。

   我们可以换用另一种设计,把对象改为指针,具体代码如下:

// user.h

class CMyClass; // CMyClass的声明,用来告诉编译器,CMyClass是一个类,但是在其他地方已定义。

class CUser {

public:

public:

string getInfo(CMyClass* pObj); // 此处用到了CMyClass*的指针

};

// user.cpp

#include “user.h”

#include “myclass.h” // 仅需要在cpp中包含该头文件即可

string CUser::getInfo(CMyClass* pObj) {

}

在改动后的代码中,在user.h中,getInfo()

在这里插入图片描述

接口不再使用CMyClass对象,而是使用CMyClass定义了一个指针。因此仅需要在user.h的开头部分使用前向声明把CMyClass声明一下即可。在真正使用的地方是在user.cpp中,因为getInfo需要使用CMyClass指针调用接口,所以在user.cpp中增加了

#include “myclass.h”。这样就无需在user.h中包含myclass.h了。

结语:

我们所作的改动设计:在头文件的接口中使用指针传递参数,在头文件开头部分使用前向声明。这种设计,将CMyClass改动时影响的代码范围控制到最小(在本例中,仅影响user.cpp,而不会影响user.h,否则会连带影响包含user.h的代码)。建议大家使用前向声明的方式使用引入的类,避免直接#include

类的头文件。

猜你喜欢

转载自blog.csdn.net/weixin_45713725/article/details/108939503
今日推荐