C with Classes 中

连接模型

需要考虑的问题:

  1. 分别编译应该能使用传统的 C, UNIX/DOS 风格的连接器。
  2. 连接应该具有类型安全性。
  3. 连接过程不应该要求任何形式的数据库。
  4. 应该很容易并且高效地与采用其他语言(如 C,汇编,Fortran)写出的程序片段连接到一起。

对于 C 来说 头文件是保证一致性的关键。C++ 沿袭了这种模式。
与 C 一样 C++也是按名称等价而不是按结构等价的,通过布局相容性来保证可以使用显式的转换,以便能提供低级的转换。

纯朴的实现

直接使用 C 的连接器的一些思考。

  1. 时间和技术上要求简单兼容 C。
  2. C 对于名称空间的隔离比较弱。
  3. 把 C++ 当前整个系统中的一个语言。
  4. 连接兼容性比代码兼容性重要。

对象连接模型

C with Class 中的对象简单地就是一个 C 结构 。
对象大小也就是各成员大小+内存对齐所需要的一些填充。
生成的 C 代码中每一个成员函数有一个this 指针。this 之所有叫 this 因为是受 Simula 影响,是指针而不是引用是因为当时 C++ 还没有引用 。

静态类型检查

那时的 C 是缺少静态类型检查的。 C with Classes 为兼容 C,一开始也允许调用不加声明的函数。
一开始 在 C 中 f() 是表示一个可以任意个数参数类型的函数。于是 C with Classes 添加了 f(void) 用于表示不接受参数的函数。 后来都改成了 f()表示不接受参数的函数。

窄转换

一开始是想避免隐式的窄转换,但是检查 C 程序发现,有大量从int 变量直接到 char 的窄转换,有的的其他转换也是有意为之。为了兼容 C,只要默认也支持隐式的窄转换。

警告的使用

对于 longintdoubleint 的转换编译器会发警告,但是从 intchar没有。Stroustrup 决定将警告只用在“超过90%的可能性是造成实际错误”的情况,这样做的意图是使程序员意识到忽略 C++的警告将是一种愚蠢的行为。

为什么是 C

C with Classes 选择 C 基于以下理由:

  1. C 很灵活。
  2. C 是高效的。
  3. C 是可用的。
  4. C 是可移植的。

A programming language serves two related purposes: it provides a vehiche for the programmer to specify actions to be executed and a set of concepts for the programmer to use when thinking about what can be done. The first aspect ideally requires a language that is "close to the machine," so that all important aspects of a machine are handled simply and efficiently in a way that is reasonably obvious to the programmer. The C language was primarily designed with this in mind. The second aspect ideally requires a language that is "close to the problem to be solved" so that the concepts of a solution can be expressed directly and concisely. The facilities added to C to create C++ were primarily designed with this in mind.

语言设计并不是从某个第一原理出发的设计,而是一种需要经验,试验和有效工程折中的艺术。

语法问题

C 声明的语法

  1. C 中同时带有前缀和后缀的声明容易带来混乱。如 int *p[10];,问题在于
    *(“指向”)是前缀,而 [](“数组”)和()(“函数返回”)是后缀。这迫使人们在出现歧义时必须使用括号。例如:
int* v[10]; /* array of pointers to ints*/
int (*p)[10]; /*pointer to array of ints*/
  1. 那时 C 允许省略类型描述符(并默认为是 int)也带来许多复杂的情况。
  2. ANSI C 后面也采纳了 C++ 将参数类型的定义写在函数括号里面的写法。

结构标志与类型名

在 C 中声明结构变量时结构的名称(结构标志)之前必须出现关键字 struct
,例如: struct buffer a; ,但是这让人感觉用户自定义类型在语法上变成了二等公民,所以在 C++中,进行了简化,即 buffer a;,因为在 C++中,struct,union,class 的名称本身就是类型名,不再需要特定的语法标识符。
不过由此造成的与 C 的兼容性的问题也持续了很多年。比如下面的代码:

struct S { int a; };
int S;
void f(struct S x){
  x.a = s; // S is an int variable
}

为此,C++对于 C 的多名称空间的解决办法是:一个名称可以指称一个类同时也可以指称一个函数或者一个变量。如果某个名称真的同时指称着这两种不同的东西,那么这个名称本身指称的就是那个非类的东西,除非在前面明显地加上了关键字struct,union,class

语法的重要性

多数人过分关注语法的问题而损害了类型方面的问题。

在 C++设计中,最关键的问题总与类型,歧义性,访问控制等有关,而不是语法方面的问题。

你可能感兴趣的:(C with Classes 中)