详细说明C 编译的编写及其代码问题
创始人
2024-06-20 05:40:57
0

为每一个软件行业的从业人员,无论是开发人员、项目经理、还是测试人员,也要不断适应这个趋势,我认为C++编译只会使我们的工作更简单和更轻松,希望本文能教会你更多东西。

如果这是你购买的库的设计问题,你对它无计可施(除了换一个更好的库),但你可以将你自己的代码组织得更好一些,以求得将修改代码后的重新编译工作降到最少。这样的设计会更好,更有可维护性,因为它们展示了更好的概念上的分离。

看看这个典型的面向对象的C++编译程序例子:

  1. class Shape {  
  2.  
  3.     public:     // 使用Shapes的用户的接口  
  4.  
  5.         virtual void draw() const;  
  6.  
  7.         virtual void rotate(int degrees);  
  8.  
  9.         // ...  
  10.  
  11.     protected:  // common data (for implementers of Shapes)  
  12.  
  13.         Point center;  
  14.  
  15.         Color col;  
  16.  
  17.         // ...  
  18.  
  19.     };  
  20.  
  21.    
  22.  
  23.     class Circle : public Shape {  
  24.  
  25.     public:   
  26.  
  27.         void draw() const;  
  28.  
  29.         void rotate(int) { }  
  30.  
  31.         // ...  
  32.  
  33.     protected:  
  34.  
  35.         int radius;  
  36.  
  37.         // ...  
  38.  
  39.     };  
  40.  
  41.    
  42.  
  43.     class Triangle : public Shape {  
  44.  
  45.     public:   
  46.  
  47.         void draw() const;  
  48.  
  49.         void rotate(int);  
  50.  
  51.         // ...  
  52.  
  53.     protected:  
  54.  
  55.         Point a, b, c;  
  56.  
  57.         // ...  
  58.  
  59.     };   

设计思想是,用户通过Shape的public接口来操纵它们,而派生类(例如Circle和Triangle)的实现部分则共享由protected成员表现的那部分实现(implementation)。这不是一件容易的事情:确定哪些实现部分是对所有的派生类都有用的,并将之共享出来。

因此,与public接口相比,protected成员往往要做多得多的改动。举例来说,虽然理论上“中心”(center)对所有的图形都是一个有效的概念,但当你要维护一个三角形的“中心”的时候,是一件非常麻烦的事情——对于三角形,当且仅当它确实被需要的时候,计算这个中心才是有意义的。#t#

protected成员很可能要依赖于实现部分的细节,而Shape的用户(译注:user此处译为用户,指使用Shape类的C++编译,下同)却不见得必须依赖它们。举例来说,很多(大多数?)使用Shape的代码在逻辑上是与“颜色”无关的,但是由于Shape中“颜色”这个定义的存在,却可能需要一堆复杂的头文件,来结合操作系统的颜色概念。

当protected部分发生了改变时,使用Shape的代码必须重新编译——即使只有派生类的实现部分才能够访问protected成员。于是,基类中的“实现相关的信息”(information helpful to implementers)对用户来说变成了象接口一样敏感的东西,它的存在导致了实现部分的不稳定,用户代码的无谓的重编译(当实现部分发生改变时),以及将头文件无节制地包含进用户代码中(因为“实现相关的信息”需要它们)。有时这被称为“脆弱的基类问题”(brittle base class problem)。

一个很明显的解决方案就是,忽略基类中那些象接口一样被使用的“实现相关的信息”。换句话说,使用接口,纯粹的接口。也就是说,用抽象基类的方式来表示接口:

  1. class Shape {  
  2.  
  3.     public:     //使用Shapes的用户的接口  
  4.  
  5.         virtual void draw() const = 0;  
  6.  
  7.         virtual void rotate(int degrees) = 0;  
  8.  
  9.         virtual Point center() const = 0;  
  10.  
  11.         // ...  
  12.  
  13.    
  14.  
  15.         // 没有数据  
  16.  
  17.     };  
  18.  
  19.    
  20.  
  21.     class Circle : public Shape {  
  22.  
  23.     public:   
  24.  
  25.         void draw() const;  
  26.  
  27.         void rotate(int) { }  
  28.  
  29.         Point center() const { return center; }  
  30.  
  31.         // ...  
  32.  
  33.     protected:  
  34.  
  35.         Point cent;  
  36.  
  37.         Color col;  
  38.  
  39.         int radius;  
  40.  
  41.         // ...  
  42.  
  43.     };  
  44.  
  45.    
  46.  
  47.     class Triangle : public Shape {  
  48.  
  49.     public:   
  50.  
  51.         void draw() const;  
  52.  
  53.         void rotate(int);  
  54.  
  55.         Point center() const;  
  56.  
  57.         // ...  
  58.  
  59.     protected:  
  60.  
  61.         Color col;  
  62.  
  63.         Point a, b, c;  
  64.  
  65.         // ...  
  66.  
  67.     };   

现在,用户对C++编译与派生类的实现部分的变化之间的关系被隔离了。我曾经见过这种技术使得编译的时间减少了几个数量级。

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...