条款34:将文件间的编译依赖性降至最低

条款34:将文件间的编译依赖性降至最低

ID:14200083

大小:42.00 KB

页数:13页

时间:2018-07-26

条款34:将文件间的编译依赖性降至最低_第1页
条款34:将文件间的编译依赖性降至最低_第2页
条款34:将文件间的编译依赖性降至最低_第3页
条款34:将文件间的编译依赖性降至最低_第4页
条款34:将文件间的编译依赖性降至最低_第5页
资源描述:

《条款34:将文件间的编译依赖性降至最低》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、条款34:将文件间的编译依赖性降至最低条款34:将文件间的编译依赖性降至最低假设某一天你打开自己的C++程序代码,然后对某个类的实现做了小小的改动。提醒你,改动的不是接口,而是类的实现,也就是说,只是细节部分。然后你准备重新生成程序,心想,编译和链接应该只会花几秒种。毕竟,只是改动了一个类嘛!于是你点击了一下"Rebuild",或输入make(或其它类似命令)。然而,等待你的是惊愕,接着是痛苦。因为你发现,整个世界都在被重新编译、重新链接!当这一切发生时,你难道仅仅只是愤怒吗?问题发生的原因在于,在将接口从实

2、现分离这方面,C++做得不是很出色。尤其是,C++的类定义中不仅包含接口规范,还有不少实现细节。例如:classPerson{public:Person(conststring&name,constDate&birthday,constAddress&addr,constCountry&country);virtual~Person();...//简化起见,省略了拷贝构造//函数和赋值运算符函数stringname()const;stringbirthDate()const;stringaddress()co

3、nst;stringnationality()const;private:stringname_;//实现细节DatebirthDate_;//实现细节Addressaddress_;//实现细节Countrycitizenship_;//实现细节};这很难称得上是一个很高明的设计,虽然它展示了一种很有趣的命名方式:当私有数据和公有函数都想用某个名字来标识时,让前者带一个尾部下划线就可以区别了。这里要注意到的重要一点是,Person的实现用到了一些类,即string,Date,Address和Country;

4、Person要想被编译,就得让编译器能够访问得到这些类的定义。这样的定义一般是通过#include指令来提供的,所以在定义Person类的文件头部,可以看到象下面这样的语句:#include//用于string类型(参见条款49)#include"date.h"#include"address.h"#include"country.h"遗憾的是,这样一来,定义Person的文件和这些头文件之间就建立了编译依赖关系。所以如果任一个辅助类(即string,Date,Address和Country)

5、改变了它的实现,或任一个辅助类所依赖的类改变了实现,包含Person类的文件以及任何使用了Person类的文件就必须重新编译。对于Person类的用户来说,这实在是令人讨厌,因为这种情况用户绝对是束手无策。那么,你一定会奇怪为什么C++一定要将一个类的实现细节放在类的定义中。例如,为什么不能象下面这样定义Person,使得类的实现细节与之分开呢?classstring;//"概念上"提前声明string类型//详见条款49classDate;//提前声明classAddress;//提前声明classCoun

6、try;//提前声明classPerson{public:Person(conststring&name,constDate&birthday,constAddress&addr,constCountry&country);virtual~Person();...//拷贝构造函数,operator=stringname()const;stringbirthDate()const;stringaddress()const;stringnationality()const;};如果这种方法可行的话,那么除非类的接

7、口改变,否则Person的用户就不需要重新编译。大系统的开发过程中,在开始类的具体实现之前,接口往往基本趋于固定,所以这种接口和实现的分离将大大节省重新编译和链接所花的时间。可惜的是,现实总是和理想相抵触,看看下面你就会认同这一点:intmain(){intx;//定义一个intPersonp(...);//定义一个Person//(为简化省略参数)...}当看到x的定义时,编译器知道必须为它分配一个int大小的内存。这没问题,每个编译器都知道一个int有多大。然而,当看到p的定义时,编译器虽然知道必须为它分

8、配一个Person大小的内存,但怎么知道一个Person对象有多大呢?唯一的途径是借助类的定义,但如果类的定义可以合法地省略实现细节,编译器怎么知道该分配多大的内存呢?原则上说,这个问题不难解决。有些语言如Smalltalk,Eiffel和Java每天都在处理这个问题。它们的做法是,当定义一个对象时,只分配足够容纳这个对象的一个指针的空间。也就是说,对应于上面的代码,他们就象这样做:intmain(

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。