摘要:
使用 const 提高函数的健壮性 看到 const 关键字,C++程序员首先想到的可能是 const 常量。这可不是良好的条件 反射。如果只知道用 const 定义常量,那么相当于把火药仅用于制作鞭炮。const 更大的 魅力是它可以修饰函数的参数、返回值,甚至函数的定义体。 const 是 co 阅读全文
摘要:
类的继承与组合 对象(Object)是类(Class)的一个实例(Instance)。如果将对象比作房子,那么 类就是房子的设计图纸。所以面向对象设计的重点是类的设计,而不是对象的设计。 对于 C++程序而言,设计孤立的类是比较容易的,难的是正确设计基类及其派生类。 本章仅仅论述“继承”(Inher 阅读全文
摘要:
如何在派生类中实现类的基本函数 基类的构造函数、析构函数、赋值函数都不能被派生类继承。如果类之间存在继承 关系,在编写上述基本函数时应注意以下事项: 派生类的构造函数应在其初始化表里调用基类的构造函数。 基类与派生类的析构函数应该为虚(即加 virtual 关键字)。 阅读全文
摘要:
不要轻视拷贝构造函数与赋值函数 由于并非所有的对象都会使用拷贝构造函数和赋值函数,程序员可能对这两个函数 有些轻视。请先记住以下的警告,在阅读正文时就会多心: 本章开头讲过,如果不主动编写拷贝构造函数和赋值函数,编译器将以“位拷贝” 的方式自动生成缺省的函数。倘若类中含有指针变量,那么这两个缺省的函 阅读全文
摘要:
构造和析构的次序 构造从类层次的最根处开始,在每一层中,首先调用基类的构造函数,然后调用成 员对象的构造函数。析构则严格按照与构造相反的次序执行,该次序是唯一的,否则编 译器将无法自动执行析构过程。 一个有趣的现象是,成员对象初始化的次序完全不受它们在初始化表中次序的影响 , 只由成员对象在类中声明 阅读全文
摘要:
构造函数的初始化表 构造函数有个特殊的初始化方式叫“初始化表达式表”(简称初始化表)。初始化表 位于函数参数表之后,却在函数体 {} 之前。这说明该表里的初始化工作发生在函数体 内的任何代码被执行之前。 阅读全文
摘要:
构造函数与析构函数的起源 作为比 C 更先进的语言,C++提供了更好的机制来增强程序的安全性。C++编译器 具有严格的类型安全检查功能,它几乎能找出程序中所有的语法问题,这的确帮了程序 员的大忙。 但是程序通过了编译检查并不表示错误已经不存在了,在 “错误”的大家庭 里, “语法错误”的地位只能算是 阅读全文
摘要:
类的构造函数、析构函数与赋值函数 构造函数、析构函数与赋值函数是每个类最基本的函数。它们太普通以致让人容易 麻痹大意,其实这些貌似简单的函数就象没有顶盖的下水道那样危险。 每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝 构造函数,其它的称为普通构造函数)。对于任意一个类 A 阅读全文
摘要:
C++ 语言中的重载、内联、缺省参数、隐式转换等机制展现了很多优点,但是这些 优点的背后都隐藏着一些隐患。正如人们的饮食,少食和暴食都不可取,应当恰到好处。 我们要辨证地看待 C++的新机制,应该恰如其分地使用它们。 虽然这会使我们编程时多 费一些心思,少了一些痛快,但这才是编程的艺术。 阅读全文
摘要:
用内联取代宏代码 C++ 语言支持函数内联,其目的是为了提高函数的执行效率(速度)。 在 C 程序中,可以用宏代码提高执行效率。宏代码本身不是函数,但使用起来象函 数。预处理器用复制宏代码的方式代替函数调用,省去了参数压栈、生成汇编语言的 CALL 调用、返回参数、执行 return 等过程,从而提 阅读全文
摘要:
参数的缺省值 有一些参数的值在每次函数调用时都相同,书写这样的语句会使人厌烦。C++语言采 用参数的缺省值使书写变得简洁(在编译时,缺省值由编译器自动插入)。 阅读全文
摘要:
令人迷惑的隐藏规则 本来仅仅区别重载与覆盖并不算困难,但是 C++的隐藏规则使问题复杂性陡然增加。 这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别与重载混淆)。 阅读全文
摘要:
重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中); (2)函数名字相同; (3)参数不同; (4)virtual 关键字可有可无。 覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类); (2)函数名字相同; (3)参数相同; (4)基类函数必须有 阅读全文
摘要:
重载是如何实现的? 几个同名的重载函数仍然是不同的函数,它们是如何区分的呢?我们自然想到函数 接口的两个要素:参数与返回值。 如果同名函数的参数不同(包括类型、顺序不同),那么容易区别出它们是不同的函 数。 阅读全文
摘要:
重载的起源 自然语言中,一个词可以有许多不同的含义,即该词被重载了。人们可以通过上下 文来判断该词到底是哪种含义。 “词的重载”可以使语言更加简练。例如“吃饭”的含义 十分广泛,人们没有必要每次非得说清楚具体吃什么不可。别迂腐得象孔已己,说茴香 豆的茴字有四种写法。 在 C++程序中,可以将语义、功 阅读全文
摘要:
对比于 C 语言的函数,C++增加了重载(overloaded)、内联(inline)、const 和 virtual 四种新机制。其中重载和内联机制既可用于全局函数也可用于类的成员函数,const 与 virtual 机制仅用于类的成员函数。 重载和内联肯定有其好处才会被 C++语言采纳,但是不可 阅读全文
摘要:
我认识不少技术不错的 C++/C 程序员,很少有人能拍拍胸脯说通晓指针与内存管理 (包括我自己)。我最初学习 C 语言时特别怕指针,导致我开发第一个应用软件(约 1 万行 C 代码)时没有使用一个指针,全用数组来顶替指针,实在蠢笨得过分。躲避指针 不是办法,后来我改写了这个软件,代码量缩小到原先的一 阅读全文
摘要:
运算符 new 使用起来要比函数 malloc 简单得多,例如: int *p1 = (int *)malloc(sizeof(int) * length); int *p2 = new int[length]; 这是因为 new 内置了 sizeof、类型转换和类型安全检查功能。 对于非内部数据类 阅读全文
摘要:
函数 malloc 的原型如下: void * malloc(size_t size); 用 malloc 申请一块长度为 length 的整数类型的内存,程序如下: int *p = (int *) malloc(sizeof(int) * length); 我们应当把注意力集中在两个要素上:“类 阅读全文
摘要:
内存耗尽怎么办? 如果在申请动态内存时找不到足够大的内存块,malloc 和 new 将返回 NULL 指针, 宣告内存申请失败。通常有三种方式处理“内存耗尽”问题。 阅读全文