设计与编程:C++的艺术与实践
立即解锁
发布时间: 2025-08-22 00:47:49 阅读量: 2 订阅数: 16 


C++编程语言精髓与实践
### 设计与编程:C++的艺术与实践
在软件开发的世界里,编程语言的选择和设计方法的运用至关重要。C++作为一种强大的编程语言,为软件设计提供了丰富的特性和工具。本文将深入探讨C++在设计中的应用,包括类、继承、类型检查等关键概念,以及如何避免常见的设计误区。
#### 1. 编程语言与设计的关系
选择编程语言如同选择建造桥梁的材料,不同的材料会影响桥梁的设计,反之亦然。同样,为软件选择语言需要对多种语言有一定了解,而成功设计软件则需要对所选实现语言有详细的认识。
C++为设计师提供了许多特性,能将设计的基本概念直接在编程语言中表示出来。这有助于实现、维护设计与实现之间的对应关系、促进设计师与实现者之间的沟通,并支持构建更好的工具。
然而,设计师有时会因各种原因未能充分利用C++的特性,常见的情况有以下几种:
|序号|表现|对应背景|
| ---- | ---- | ---- |
|1|忽略类,将设计限制在C子集|C、传统CASE或结构化设计背景|
|2|忽略派生类和虚函数,仅使用数据抽象子集|Ada83、Visual Basic或数据抽象背景|
|3|忽略静态类型检查,模拟动态类型检查|Smalltalk或Lisp背景|
|4|忽略编程,试图消除程序员|非技术或非常专业的背景|
|5|只关注类层次结构|强调“纯”面向对象编程的背景|
#### 2. 忽略类的设计问题
忽略类的设计会使C++程序大致等同于C或COBOL程序,这种“编程语言无关”的设计虽然有一定优势,如便于使用传统数据库,但在处理复杂应用时会暴露出问题。
传统的过程式编程(功能分解)与面向对象设计有根本区别。功能分解导致数据抽象不足,使设计在面对变化时不够灵活,难以使用工具,不适合并行开发和并发执行。
例如,在一个交互式CASE系统中,忽略类对数据抽象的支持会使代码无法直接反映设计,导致代码行数过多、缺乏类型检查,难以维护。
```mermaid
graph LR
A[功能分解] --> B[数据抽象不足]
B --> C[设计不灵活]
B --> D[难以使用工具]
B --> E[不适合并行开发]
B --> F[不适合并发执行]
```
#### 3. 避免继承的问题
避免使用继承会使程序无法充分利用C++的关键特性。有人认为继承是实现细节、违反信息隐藏或使与其他软件的协作更困难,但这些观点忽略了类层次结构能直接建模应用领域中概念之间关键关系的作用。
在大型项目中,“不使用继承”的策略会导致系统难以理解和灵活度降低,继承可能会被用更传统的语言和设计结构“伪造”。实际上,类层次结构在很多情况下有助于理解应用和表达解决方案,但也需要谨慎使用,避免滥用。
#### 4. 忽略静态类型检查的问题
在设计阶段忽略静态类型检查,常以“类型是编程语言的产物”等理由为借口。然而,类和类层次结构在设计中非常有用,能帮助明确概念及其关系。
静态类型检查是一种基本的设计工具,能确保软件组件之间的兼容性,减少运行时测试的使用,提高效率并降低多人项目集成阶段的成本。
例如,以下代码展示了动态类型检查和静态类型检查的区别:
```cpp
// 动态类型检查示例
Stack s; // Stack can hold pointers to objects of any type
void f() {
s.push(new Saab900);
s.push(new Saab37B);
s.pop()->takeoff(); // fine: a Saab 37B is a plane
s.pop()->takeoff(); // run-time error: car cannot take off
}
// 静态类型检查示例
Stack<Plane*> s; // Stack can hold pointers to Planes
void f() {
s.push(new Saab900); // error: a Saab900 is not a Plane
s.push(new Saab37B);
s.pop()->takeoff(); // fine: a Saab 37B is a plane
s.pop()->takeoff();
}
```
静态类型检查将错误检测从运行时提前到编译时,能显著提高程序的可靠性。
#### 5. 避免编程的问题
编程成本高、不可预测,且代码可靠性不足,因此有人想完全消除编程活动。但在特定领域,如数学、状态机和关系数据库,或有通用框架的领域,如图形用户界面、网络模拟和数据库模式,代码生成技术能发挥作用。
然而,将规范技术扩展到缺乏理论基础的领域会使规范语言变得复杂,失去简洁性和良好的基础。同时,忽略传统编程技术和直接操作技术在其适用领域的应用也是不明智的。
#### 6. 过度使用类层次结构的问题
虽然类层次结构和多态操作能解决很多问题,但并非所有概念都适合用类层次结构表示。将所有编程工件强制放入单一层次结构可能会引入人为的相似性,掩盖真实的关系。
在设计中,应根据分析或编程发现的概念共性来使用类层次结构。对于一些类,使用非虚函数和私有数据进行更严格的封装可能更合适。当操作有多个参数且需要平等对待时,非成员函数是更好的选择。
#### 7. 类的概念与关系
类是面向对象设计和编程的核心,程序是对现实某些方面的建模,类代表应用的基本概念。分析类之间的关系对于系统设计至关重要,主要包括以下几种关系:
- **继承关系**:用于表示概念之间的层次关系,如模拟城市交通流时,各类车辆的继承关系。
```cpp
class Vehicle { /* ... */ };
class Emergency { /* ... */ };
class Car : public Vehicle { /* ... */ };
class Truck : public Vehicle { /* ... */ };
class PoliceCar : public Car, protected Emergency { /* ... */ };
class Ambulance : public Car, protected Emergency { /* ... */ };
class FireEngine : public Truck, protected Emergency { /* ... */ };
class HookAndLadder : public FireEngine { /* ... */ };
```
- **包含关系**:有两种主要方式表示包含对象,直接声明对象成员或声明指针/引用成员。直接成员通常更高效且不易出错,但指针成员在需要更改指向对象时更有用。
```cpp
class X {
public:
X(int);
// ...
};
class C {
X a;
X* p;
X& r;
public:
C(int i, int j, int k) : a(i), p(new X(j)), r(*new X(k)) { }
~C() { delete p; delete &r; }
};
```
- **使用关系**:了解一个类使用其他类的方式对于表达和理解设计很关键,但C++只隐式支持这种依赖,需要工具或仔细阅读代码来提取信息。
- **编程内关系**:当编程语言无法直接支持设计概念时,需要使用传统的映射方式。例如,设计中的委托概念在C++中需要通过代码模拟,但这种模拟不如直接对应关系好,且不易被工具处理。
```cpp
class B {
// ...
void f();
void g();
void h();
};
class A {
B* p;
// ...
void f();
voi
```
0
0
复制全文
相关推荐










