C with Classes 的诞生
- 准备分析 UNIX 内核以用于计算机网络,需要开发一些合适的工具。
- 1979年10月第一版本 Cpre 给C 加了 类似Simula 的类机制,并发模拟。
- 语言本身并不提供并发的“原语”,认为更适合通过库来提供。
- 目标在运行时间和代码紧凑性与 C 媲美。为了保证数据布局方面与 C 兼容,没有在类对象中放任何的 "hosekeeping data"。
- 维持了低级操作和不安全特征,但是应该提供适当的语言特性和工具以帮助程序员避免公认的圈套和陷阱。
特征概览
其中后面三个特性为 1981 年添加:
- 类
- 派生类(但是没有虚函数)
- 公用/私用的访问控制
- 构造函数和析构函数
- 调用和返回函数(后来删除了)
- friend 类
- 函数参数的检查和类型转换
- inline 函数
- 默认参数
- 赋值运行符的重载
类
下面是一个 C with Classes 语法的类相关代码:
class stack{
char s[SIZE];
char* min;
char* top;
char* max;
void new(); /* initialize function(constructor)*/
public:
void push(char);
char pop();
}
char stack.pop(){
if(top <=min)error("stack underflow");
return *(--top);
}
// 使用
class stack s1,s2; /*two stack variables*/
class stack * p1 = &s2; /* p1 points to s2*/
class stack * p2 = new stack; /* p2 points to stack object allocated on free store*/
s1.push('h'); /*use object directly*/
p1->push('s'); /*use object through pointer*/
反应出如下设计决策
- 程序员描述类型,通过类型建立对象。使用
class
这个术语而不是type
是因为觉得 Simula 的这个术语很合适。 - 用户定义类型可以是真正的局部变量,意味着不一定要在堆中分配。
- 采用编译时的访问控制。默认只有类声明中给出的函数才可以使用各个类成员的名称。
- 对于函数成员,需要描述其完整的类型(即包括返回类型,也包括参数类型)。
- 函数的定义通常写在其他地方,以使类声明看起来更像一个接口描述。(意味着更容易编译,可以直接使用 C 的连接技术)
-
new()
是构造函数。 - 同时提供了指针和非指针类型。
- 和 C 语言一样,对象的分配可以有3种方式:在堆栈上(作为自动对象),在固定地址(静态对象),或者在自由存储区(在堆)。与 C 不同的是,提供了
new
和delete
运算符。
运行时的效率
C++设计规则
只提供一个特征是不够的,还必须以一种实际上可以负担得起的形式来提供它。
inline 机制
- inline 可以减少函数开销。
- C with class 时只有在将函数定义在函数声明处才当作是
inline
的。 - 后面增加了
inline
关键字。不过这只是一种对编译器的提示。(逻辑上来说递归的函数无法 inline)