详细说明C++编译的编写及其代码问题

开发 后端
你要对C++编译的程序设计得非常糟糕,以至于编译器不得不检查数以百计的头文件和数万行代码。理论上来说,这是可以避免的。

为每一个软件行业的从业人员,无论是开发人员、项目经理、还是测试人员,也要不断适应这个趋势,我认为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++编译与派生类的实现部分的变化之间的关系被隔离了。我曾经见过这种技术使得编译的时间减少了几个数量级。

责任编辑:chenqingxiang 来源: CSDN
相关推荐

2010-01-19 09:54:19

C++代码

2010-01-13 13:27:00

C++优化

2010-01-19 13:43:59

C++函数

2010-01-28 11:08:09

C++变量

2010-01-08 17:06:52

C++代码

2010-01-18 10:34:21

C++编译器

2010-01-08 16:10:59

C++语言

2009-12-07 13:12:18

WFC端口

2010-01-11 13:31:03

C++语言

2010-02-22 13:20:58

Python中文问题

2009-12-09 15:40:04

Visual Stud

2010-02-23 10:14:29

Python 源代码

2014-09-16 09:57:56

INotifyProp

2010-01-11 11:27:25

C++语言

2010-02-24 10:07:28

Python虚拟机

2009-12-28 09:26:09

ADO对象

2010-10-13 14:28:09

mysql日志文件

2009-12-08 17:34:25

WCF的配置

2010-03-18 16:53:56

骨干交换机

2010-02-04 14:41:52

Android菜单类型
点赞
收藏

51CTO技术栈公众号