将文件间的编译依存关系降至最低
2017-07-06 17:11
567 查看
假设有三个类ComplexClass, SimpleClass1和SimpleClass2,将类的声明与类的实现分开,这样共对应于6个文件,分别是
ComplexClass.h,ComplexClass.cpp
SimpleClass1.h,SimpleClass1.cpp
SimpleClass2.h,SimpleClass2.cpp
对应的头文件和源文件要保持一致性。
(1)ComplexClass.h的内容如下
如果SimpleClass1.h发生了变化,比如添加了一个新的成员变量,则:
SimpleClass1.cpp要重编
SimpleClass2因为与SimpleClass1是独立的,所以SimpleClass2是不需要重编的。
ComplexClass需要重编,因为ComplexClass的头文件里面包含了SimpleClass1.h(使用了SimpleClass1作为成员对象的类),而且所有使用ComplexClass类的对象的文件,都需要重新编译!
如果SimpleClass1.cpp发生了变化,比如改变了一个成员函数的实现(换了一种排序算法等),但SimpleClass1.h没有变,则:
SimpleClass1一定会重编
SimpleClass2因为独立性不需要重编
ComplexClass不需要重编,因为编译器重编的条件是发现一个变量的类型或者大小跟之前的不一样了,但现在SimpleClass1的接口并没有变化,只是改变了实现的细节,所以编译器不会重编。
(2)尝试用类前置声明代替#include<>,修改ComplexClass.h的内容如下
但如果SimpleClass1作为一个函数的形参,或者是函数返回值,用
(3)利用指针,修改ComplexClass.h的内容如下
此时在ComplexClass.cpp是类ComplexClass的实现码,因此,必然需要包含
其实做的就是将ComplexClass.h的 #include”SimpleClass1.h” 移至ComplexClass1.cpp里面,而在原位置放置class SimpleClass1(类前置声明)。
假设这时候SimpleClass1.h发生了变化,则:
SimpleClass1自身一定会重编
SimpleClass2当然还是不用重编的
ComplexClass.cpp因为包含了SimpleClass1.h,所以需要重编,但换来的好处就是所有用到ComplexClass的其他地方,它们所在的文件不用重编了!因为ComplexClass的头文件没有变化,接口没有改变!
总结一下,对于C++类而言,如果它的头文件变了,那么所有这个类的对象所在的文件都要重编,但如果它的实现文件(cpp文件)变了,而头文件没有变(对外的接口不变),那么所有这个类的对象所在的文件都不会因之而重编。
因此,避免大量依赖性编译的解决方案就是:在头文件中用class声明外来类,用指针或引用代替变量的声明;在cpp文件中包含外来类的头文件。
参阅博客
ComplexClass.h,ComplexClass.cpp
SimpleClass1.h,SimpleClass1.cpp
SimpleClass2.h,SimpleClass2.cpp
对应的头文件和源文件要保持一致性。
(1)ComplexClass.h的内容如下
#ifndef COMPLESS_CLASS_H #define COMPLESS_CLASS_H #include “SimpleClass1.h” #include “SimpleClass2.h” class ComplexClass { SimpleClass1 xx; SimpleClass2 xxx; }; ... #endif
如果SimpleClass1.h发生了变化,比如添加了一个新的成员变量,则:
SimpleClass1.cpp要重编
SimpleClass2因为与SimpleClass1是独立的,所以SimpleClass2是不需要重编的。
ComplexClass需要重编,因为ComplexClass的头文件里面包含了SimpleClass1.h(使用了SimpleClass1作为成员对象的类),而且所有使用ComplexClass类的对象的文件,都需要重新编译!
如果SimpleClass1.cpp发生了变化,比如改变了一个成员函数的实现(换了一种排序算法等),但SimpleClass1.h没有变,则:
SimpleClass1一定会重编
SimpleClass2因为独立性不需要重编
ComplexClass不需要重编,因为编译器重编的条件是发现一个变量的类型或者大小跟之前的不一样了,但现在SimpleClass1的接口并没有变化,只是改变了实现的细节,所以编译器不会重编。
(2)尝试用类前置声明代替#include<>,修改ComplexClass.h的内容如下
#include “SimpleClass2.h” class SimpleClass1;//类前置声明 class ComplexClass { SimpleClass1 xx; SimpleClass2 xxx; };//不能通过编译,因为编译器需要知道ComplexClass成员变量SimpleClass1对象的大小,而这些信息仅由声明class SimpleClass1是不够的。
但如果SimpleClass1作为一个函数的形参,或者是函数返回值,用
class SimpleClass1声明就够了。如:
class SimpleClass1; SimpleClass1 GetSimpleClass1() const;//编译成功
(3)利用指针,修改ComplexClass.h的内容如下
#include “SimpleClass2.h” class SimpleClass1; class ComplexClass: { SimpleClass1* m_sc1; SimpleClass2 m_sc2; }; //可通过编译,因为编译器视所有指针为一个字长(在32位机器上是4字节,64是8字节),因此class SimpleClass1的声明够用了。但如果要想使用SimpleClass1的方法,还是要包含SimpleClass1.h,但那是ComplexClass.cpp做的,因为ComplexClass.h只负责类变量和方法的声明。
此时在ComplexClass.cpp是类ComplexClass的实现码,因此,必然需要包含
#include "SimpleClass1.h"
#include "SimpleClass1.h" void ComplexClass::Fun() { SimpleClass1->FunMethod(); }
其实做的就是将ComplexClass.h的 #include”SimpleClass1.h” 移至ComplexClass1.cpp里面,而在原位置放置class SimpleClass1(类前置声明)。
假设这时候SimpleClass1.h发生了变化,则:
SimpleClass1自身一定会重编
SimpleClass2当然还是不用重编的
ComplexClass.cpp因为包含了SimpleClass1.h,所以需要重编,但换来的好处就是所有用到ComplexClass的其他地方,它们所在的文件不用重编了!因为ComplexClass的头文件没有变化,接口没有改变!
总结一下,对于C++类而言,如果它的头文件变了,那么所有这个类的对象所在的文件都要重编,但如果它的实现文件(cpp文件)变了,而头文件没有变(对外的接口不变),那么所有这个类的对象所在的文件都不会因之而重编。
因此,避免大量依赖性编译的解决方案就是:在头文件中用class声明外来类,用指针或引用代替变量的声明;在cpp文件中包含外来类的头文件。
参阅博客
相关文章推荐
- Effective C++ 条款31 将文件中间的编译依存关系降至最低
- 条款31:将文件间的编译依存关系降至最低(Minimize compilation dependencies between files)
- 【31】将文件间的编译依存关系降至最低
- Effective c++之 将文件间的编译依存关系降至最低
- 读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第二部分)
- 将文件间的编译依存关系降至最低(第一部分)
- 《Effective C++》读书笔记之item31:将文件间的编译依存关系降至最低
- [Effective C++ --031]将文件间的编译依存关系降至最低
- Effective C++笔记_条款31将文件间的编译依存关系降至最低
- 条款31:将文件间的编译依存关系降至最低
- 将文件间的编译依存关系降至最低(第二部分)
- [EffectiveC++]item31:将文件间的编译依存关系降至最低
- 读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第一部分)
- 条款31:将文件间的编译依存关系降至最低
- 条款31:将文件间的编译依存关系降至最低
- 1.将文件间的编译依存关系降至最低
- Effectiv C++条款31 将文件间的编译依存关系降至最低 Handle Class和Interface Class完整实现
- Effective C++笔记_条款31将文件间的编译依存关系降至最低
- 读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低
- 将文件间的编译依存关系降至最低【EC++笔记】