将文件之间的编译依赖关系降至最低

Item31:将文件间的编译依存关系降至最低 C++中,很多场景只需类的声明(class declaration)即可,无需完整定义(class definition)。声明指针或引用(无需知道类的大小和成员);声明接受或返回该类的函数(参数和返回值为指针/引用时)。改进方案:用前置声明替代#include,仅在源文件中包含必要的定义。// Person.h(改进后)class Date; 阅读详情

考虑这样几个类,A、a1、a2、B,其中A和B是要暴露给用户的类。

 

1.最初组织关系如下:

 //a1.h

#include <iostream>

class a1
{
public:
 void DoSomething()
 {
   std::cout<<"a1 do sth"<<std::endl;
 }
};

 

//a2.h

#include <iostream>

class a2
{
public:
 void DoSomething()
 {
  std::cout<<"a2 do sth"<<std::endl;
 }
};

 

//B.h

#include <iostream>

class B
{
public:
 void DoSomething()
 {
   std::cout<<"B do sth"<<std::endl;
 }
};

 

//A.h

#include "a1.h"
#include "a2.h"
#include "B.h"

class A
{
public:
 void DoSomething(); 

 B ReturnB(); 
private:
 a1 _a1;
 a2 _a2;
};

 

//A.cpp

#include "A.h"

void A::DoSomething()
{
 _a1.DoSomething();
 _a2.DoSomething();
}

B A::ReturnB()
{
 return B();
}

 

//user.cpp

#include "A.h"

 

int main()
{
 A a;
 a.DoSomething();
 a.ReturnB().DoSomething();
}

 

因此,user.cpp 中直接或间接的include了A.h B.h a1.h a2.h,而且user根本不知道已经include了 这么多.h,尤其是不知道已经include了B.h。因此,如果与接口无关类型a1.h和a2.h改变了,会导致user.cpp重新编译。

 

2.利用指针/引用进行实现之:

a1.h a2.h B.h不用更改。

//A.h

class a1;
class a2;

class B;

class A
{
public:
 void DoSomething(); 

 B ReturnB(); 
private:
 a1 *_a1;
 a2 *_a2;
};

 

//A.cpp

#include "A.h"
#include "a1.h"
#include "a2.h"
#include "B.h"

void A::DoSomething()
{
 _a1 = new a1();
 _a1->DoSomething();
 delete _a1;

 _a2 = new a2();
 _a2->DoSomething();
 delete _a2;
}

B A::ReturnB()
{
 return B();
}

 

//user.cpp

#include "A.h"
#include "B.h"//显示指明我要你

 

int main()
{
 A a;
 a.DoSomething();
 B b = a.ReturnB();b.DoSomething();
}

//此时user.cpp只是包含了A.h 和 B.h,因此a1.h和a2.h修改的时候,user.cpp不用再重新编译。但是user可以看到A.h里含有a1,a2这些毫无意义的东西,这样的话,是暴露了其内部实现,因此我们纳入一个新的类AImpl来消灭这个暴露狂。

 

3.实现AImpl,将A变成一个Handle class

a1.h a2.h B.h不变。

//AImpl.h  //真是臃肿,懒得写AImpl.cpp了

#include "a1.h"
#include "a2.h"
#include "B.h"

class AImpl
{
public:
 void DoSomething()
 {
  _a1.DoSomething();
  _a2.DoSomething();
 }

 B ReturnB()
 {
  return B();
 }
private:
 a1 _a1;
 a2 _a2;
};

 

//A.h

class AImpl;

class B;

class A
{
public:
 void DoSomething(); 

 B ReturnB(); 
private:
 AImpl *aImpl;
};

 

//A.cpp

#include "A.h"

#include "AImpl.h"

#include "B.h"

void A::DoSomething()
{
 aImpl->DoSomething();
}

B A::ReturnB()
{
 return aImpl->ReturnB();
}

 

//user.cpp不变,但是这次他看到的A.h就没有_a1和_a2这些东西了~~~~

 

以上这类方法叫做Handle class,不过我怎么觉得没什么大用啊,c++标准库里有应用吗?谁知道,麻烦告诉小弟声~~~

另外Effective C++里还有另外一种方法,叫做Protocal class,相貌如下:

class AProtocal
{
 A *makeA();
 void DoSomething();
 B ReturnB();
}

所以实现也就不言自明了,另外比较高级的实现方法,就是将A public继承一个接口类,并private 继承一个实现类,具体见书本吧。

 

【Effective C++】将文件之间的编译关系降到最低 C++ 的编译依赖关系 如果你对 C++ 的某个实现文件做了修改,你可能会发现,所有与这个类有关的其他项目文件都需要重新编译。这主要归咎于 C++ 并没有把 “将接口与实现分离” 这件事情做得很好。比如说像下面这样: #include<string> #include"date.h" #include"address.h" class Person { //对外接口 public: Person(const std::string& name, const Date& b 阅读详情

相关推荐

从标记基因到功能分析:手把手教你人工注释单细胞亚群的完整流程

本文详细介绍了人工注释单细胞亚群的完整流程,从标记基因筛选到功能分析验证,特别针对肿瘤微环境、发育轨迹等复杂场景提供解决方案。通过差异表达分析、多维数据整合和实验验证,帮助研究者准确识别细胞类型,提升单细胞转录组研究的生物学解读深度。

jenkins8butler的博客 244

减少文件之间的编译依赖

        C++开发中,如果不注意,随便修改一个头文件中的定义,会导致很多引用(indlude)到该头文件的文件重新编译,觉得很浪费时间,所以要尽量减少文件之间的编译依赖。        除了标准库,尽量不要在头文件中直接包含要使用的类的头文件,虽然直接包含头文件对于客户端程序员有方便之处(包含了你的头文件就可以直接使用依赖的东西),但对于大项目,会耗费大量的编译时间,不可取。       

lostown的专栏 2266

【驱动适配】高通sa522平台tac5x1x驱动适配全指南

本手册详细介绍了TAC5301-Q1音频编解码器在高通sa525平台Linux系统下的驱动适配流程。主要内容包括:1)TAC5301-Q1核心特性(车载级音频Codec、关键接口和功能);2)驱动适配依赖(高通声卡驱动、ALSA SoC框架等);3)I2S协议原理及主从模式说明;4)硬件准备与检查要点;5)完整的驱动移植步骤(代码移植、Kconfig/Makefile修改、设备树配置)。该手册适用于嵌入式音频开发工程师快速完成TAC5301-Q1芯片的驱动移植与验证工作。

嵌入式博哥的博客 303

条款31、将文件间的编译依赖依存关系降至最低

这里可以看到main.cc 依赖person.h, 至于personimpl.h的成员变量(实现),personimpl.cc怎么改成员函数,编译的时候都不会影响main.cc, 因为没有依赖关系。在做测试的遇到一个问题,就是虚基类,析构函数要么不申明(编译器自己生成),如果申明的话一定要给一个定义,纯虚函数直接=0就行,不用再给定义。接下来是personimpl.h 和personimpl.cc。接下的main函数只要依赖接口person.h就行了.这个在设计模式专栏总结过,这里也是一个意思,具体参考。

feng__shuai的博客 243

当我们谈论Unidbg时我们在谈什么

文章目录一、前言二、使用Unidbg的工作量是什么三、补环境补的是什么3.1 运行环境缺失3.2 上下文缺失四、Unidbg 不是所有情况下最优的解决方案五、Unidbg在大多数情况下是好的方案六、Unidbg和风控无关七、尾声 一、前言 这是一篇漫谈Unidbg的文章,我对Unidbg的使用和理解都还很浅,日后会更新或修改看法,欢迎大佬指点,也期待同侪讨论。 二、使用Unidbg的工作量是什么 我们常规使用Frida + IDA的动静态分析中,工作可能是这样的 找线索→Frida Hook验证→验证成功继

lilac的博客 5788

Open5GS实战:从零搭建树莓派5G核心网并与商用终端联调

本文详细介绍了如何在树莓派5上从零开始搭建基于Open5GS的5G核心网,涵盖系统准备、依赖安装、源码编译、关键配置修改及服务启动全流程。通过整合SDR基站与商用终端进行端到端联调,为开发者和研究者提供了一个低成本、可实践的5G网络实验平台,助力物联网与边缘计算应用的本地化测试与验证。

weixin_29194255的博客 157

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

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

xiaoding133的专栏【Stay hungry,Stay foolish】 2462

从C到汇编:单片机汇编语言核心概念迁移指南

本文详细介绍了从C语言迁移到单片机汇编语言的核心概念与实践指南,特别适合嵌入式开发者。文章深入探讨了汇编语言在性能优化、时序控制等方面的独特优势,并提供了变量存储、函数实现、流程控制等关键概念的对应关系,帮助开发者高效掌握汇编编程技巧。

weixin_31887307的博客 346

【拓扑排序】:如何确定代码源文件的编译依赖关系?

从今天开始,我们就进入了专栏的高级篇。相对基础篇,高级篇涉及的知识点,都比较零散,不是太系统。所以,我会围绕一个实际软件开发的问题,在阐述具体解决方法的过程中,将涉及的知识点给你详细讲解出来。 所以,相较于基础篇“开篇问题 - 知识讲解 - 回答开篇 - 总结 - 课后思考”这样的文章结构,高级篇我稍作了些改变,大致分为这样几个部分:“问题阐述 - 算法解析 - 总结引申 - 课后思考”。 好...

南方以北 2164

UFS软件分区介绍

本文主要介绍了ufs软件分区管理的概况,能够使大家对软件分区有个大体的认识

肥匪斐's blogs 1万+

鸿蒙ArkUI内部API10以及11开发,输入框唤起输入法键盘,页面会被顶起的解决办法

鸿蒙ArkUI内部API10以及11开发,输入框唤起输入法键盘,页面会被顶起的解决办法

zmx781284440的博客 3214

极客时间——数据结构与算法(43) 拓扑排序:如何确定代码源文件的编译依赖关系?

从今天开始,我们就进入了专栏的高级篇。相对基础篇,高级篇涉及的知识点,都比较零散,不是太系统。所以,我会围绕一个实际软件开发的问题,在阐述具体解决方法的过程中,将涉及的知识点给你详细讲解出来。 所以,相较于基础篇“开篇问题 - 知识讲解 - 回答开篇 - 总结 - 课后思考”这样的文章结构,高级篇我稍作了些改变,大致分为这样几个部分:“问题阐述 - 算法解析 - 总结引申 - 课后思考”。 好...

weixin_40805079的博客 610

【unity游戏开发入门到精通——UGUI】文本控件 —— TextetMeshPro新文本控件(TextMeshPro - Text(UI)和TextMeshPro - Text)

文本组件是UGUI中最常用的组件,它的作用是对文本数据进行处理并显示。UGUI的文本组件可以分两为种——Text旧文本控件、TextMeshPro新文本组件。本文主要是介绍TextMeshPro新文本控件,而TextMeshPro新文本控件又可以分为两种——TextMeshPro - Text(UI)和TextMeshPro - Text。TextMeshPro是Unity收购的一个第三方插件,现在已经自动内置到编辑器中,只要使用一次就会自动导入到工程。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 3751

小心得:处理两个头文件互调,死循环情况(将文件之间的编译依赖关系降至最低)

本来没这么关注这个问题,但是今天应用两个类之间互调,发现出现死循环显现,就是传说中的泥中有我我中有你,都是预编译搞的鬼,一旦加入#include然后两个类就是开始我 把你的源代码复制过来,你又把我得源代码复制过来,当然vc不会这么干了,他会给报错,说其中一个类为定义。 解决这个问题之前,要先说一下这个声明和定义分开的问题,就是实现和接口分离问题,这是我的简单理解,欢迎提意见。 简单来说就是类

思想的可见性 952

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Effective_C++_条款三十一:将文件间的编译依存关系降至最低

在说这一条款之前,先要了解一下C/C++的编译知识,假设有三个类ComplexClass, SimpleClass1和SimpleClass2,采用头文件将类的声明与类的实现分开,这样共对应于6个文件,分别是ComplexClass.h,ComplexClass.cpp,SimpleClass1.h,SimpleClass1.cpp,SimpleClass2.h,SimpleClass2.cpp。...

Likes的博客 310

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

条款31:将文件间的编译依存关系降至最低

相依于声明式,不要相依于定义式 定义某类型的references和pointer,只需用到该类型的声明式定义某类型的objects,就需要用到该类型的定义式当声明一个函数而它用到某个类,或者该函数以by value方式传递该类的参数(返回值)时,不需要该类的定义式 class Person { public: Person(const std::string& name, const

l1064782986的专栏 320

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

将文件之间的编译依存降至最低

对C++类而言,如果它的头文件(.h)变了,那么这个类的对象所在的文件都有重编。但如果它的实现文件(.cpp)变了,而头文件(.h)没有变(对外的接口没有变),那么这个类的对象所在的文件都不会因之重编。因此,避免大量依赖性编译的解决方案就是:在头文件中用class声明外来类,用指针或引用代替变量的声明;在cpp文件中包含外来类的头文件。【精选】将文件间的编译依存关系降至最低_将文件间的依存关系_Aced96的博客-优快云博客。

qq_58158950的博客 97

将文件间的编译依存关系降至最低

结论:避免大量依赖性编译的解决方案是,在头文件中用 class声明 外来类,用指针或引用来代替变量的声明;在CPP文件中包含外来类的头文件。 好处: 如果A.h发生改变,所有包含类A对象的文件都要重新编。 在B.cpp中包含A.h的好处是:所有用到类B对象的文件都不用重新编译。 // A.h class A{ funcA(); }; // A.cpp A的实现 // B.h class A; class B{ A* xx; //用A的指针来替代变量的声明 }; // B.cpp

Aced96的博客 1424

C++ 接口与实现分离技术---如何将文件间的编译关系降至最低

    要将文件间的编译关系降到最低,就是要以“声明的依存性”替换“定义的依存性”。什么是“声明的依存性”和“定义的依存性”呢,简单的说是这样:  比如 //Person.h #ifndef PERSON#define PERSON#include "Date.h"#include "Address.h"class Person{ public:

夏爵爷的脚步 1963

31 将文件的编译依存关系降至最低

一、class定义式中包含实现细目 class Person{ public: Person(const std::string& name,const Date&birthday, const Address& addr); std::string name() const; std::string birthDate() const; std::string address() const; ... private: //实现细目

gb173652770的专栏 302

将文件间的编译依赖关系(Compilation dependency)降至最低

将文件间的编译依赖关系(Compilation dependency)降至最低

winneyDD的博客 304

条款31:将文件间的编译依存关系降至最低

条款31:将文件间的编译依存关系降至最低    (Minimize compilation dependencies between files.)内容:    在你们的开发团队中,一些有经验的工程师时不时地会教导新手一些基本的编程原则,其中"将接口从实现中分离"可能是他(她)要你必须牢记原则,因为C++并没有把它做的很好,这只能靠我们在平时的编写代码中注意这一点了,如果你不小心违背了这一原则

scofieldzhu的专栏 1316

Effective C++ 条款31:将文件间的编译依存关系降至最低

分离接口和实现:通过分离接口和实现,减少了文件之间的依赖关系。引用或指针传递:避免直接传递对象,尽量使用引用或指针来减少拷贝和依赖。声明式替代定义式:尽可能在头文件中只提供声明,避免暴露实现细节。使用 Handle 和 Interface 类:通过 handle 类和接口类设计模式来最小化依赖关系,增强系统的灵活性。减少编译依赖关系是提升大型项目可维护性和编译效率的关键,遵循这些原则有助于构建高效且易于扩展的系统。

weixin_42255569的博客 468

31:将文件间的编译依存关系降至最低

1.支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式。基于此构想的两个手段是Handle class和Interface class。2.程序库头文件应该以“完全且仅有声明式”(full and declaration-only forms)的形式存在。这种做法不论是否涉及template都适用。

cqxm11的博客 656

将文件间的编译依存关系降至最低的例子

在说这一条款之前,先要了解一下C/C++的编译知识,假设有三个类ComplexClass, SimpleClass1和SimpleClass2,采用头文件将类的声明与类的实现分开,这样共对应于6个文件,分别是ComplexClass.h,ComplexClass.cpp,SimpleClass1.h,SimpleClass1.cpp,SimpleClass2.h,SimpleClass2.cpp。...

lfc2017的博客 209
上一篇: C语言编译全过程
下一篇: 我也来写KMP
MagicxiaoZ
博客等级 码龄19年 5粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值