上一页 1 ··· 39 40 41 42 43 44 45 46 47 ··· 50 下一页
摘要: 类的继承与组合 对象(Object)是类(Class)的一个实例(Instance)。如果将对象比作房子,那么 类就是房子的设计图纸。所以面向对象设计的重点是类的设计,而不是对象的设计。 对于 C++程序而言,设计孤立的类是比较容易的,难的是正确设计基类及其派生类。 本章仅仅论述“继承”(Inher 阅读全文
posted @ 2018-08-02 13:06 borter 阅读(117) 评论(0) 推荐(0) 编辑
摘要: 如何在派生类中实现类的基本函数 基类的构造函数、析构函数、赋值函数都不能被派生类继承。如果类之间存在继承 关系,在编写上述基本函数时应注意以下事项: 派生类的构造函数应在其初始化表里调用基类的构造函数。 基类与派生类的析构函数应该为虚(即加 virtual 关键字)。 阅读全文
posted @ 2018-08-02 13:04 borter 阅读(147) 评论(0) 推荐(0) 编辑
摘要: 不要轻视拷贝构造函数与赋值函数 由于并非所有的对象都会使用拷贝构造函数和赋值函数,程序员可能对这两个函数 有些轻视。请先记住以下的警告,在阅读正文时就会多心: 本章开头讲过,如果不主动编写拷贝构造函数和赋值函数,编译器将以“位拷贝” 的方式自动生成缺省的函数。倘若类中含有指针变量,那么这两个缺省的函 阅读全文
posted @ 2018-08-02 13:02 borter 阅读(133) 评论(0) 推荐(0) 编辑
摘要: 构造和析构的次序 构造从类层次的最根处开始,在每一层中,首先调用基类的构造函数,然后调用成 员对象的构造函数。析构则严格按照与构造相反的次序执行,该次序是唯一的,否则编 译器将无法自动执行析构过程。 一个有趣的现象是,成员对象初始化的次序完全不受它们在初始化表中次序的影响 , 只由成员对象在类中声明 阅读全文
posted @ 2018-08-02 12:59 borter 阅读(271) 评论(0) 推荐(0) 编辑
摘要: 构造函数的初始化表 构造函数有个特殊的初始化方式叫“初始化表达式表”(简称初始化表)。初始化表 位于函数参数表之后,却在函数体 {} 之前。这说明该表里的初始化工作发生在函数体 内的任何代码被执行之前。 阅读全文
posted @ 2018-08-02 12:58 borter 阅读(237) 评论(0) 推荐(0) 编辑
摘要: 构造函数与析构函数的起源 作为比 C 更先进的语言,C++提供了更好的机制来增强程序的安全性。C++编译器 具有严格的类型安全检查功能,它几乎能找出程序中所有的语法问题,这的确帮了程序 员的大忙。 但是程序通过了编译检查并不表示错误已经不存在了,在 “错误”的大家庭 里, “语法错误”的地位只能算是 阅读全文
posted @ 2018-08-02 12:56 borter 阅读(156) 评论(0) 推荐(0) 编辑
摘要: 类的构造函数、析构函数与赋值函数 构造函数、析构函数与赋值函数是每个类最基本的函数。它们太普通以致让人容易 麻痹大意,其实这些貌似简单的函数就象没有顶盖的下水道那样危险。 每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝 构造函数,其它的称为普通构造函数)。对于任意一个类 A 阅读全文
posted @ 2018-08-02 12:54 borter 阅读(317) 评论(0) 推荐(0) 编辑
摘要: C++ 语言中的重载、内联、缺省参数、隐式转换等机制展现了很多优点,但是这些 优点的背后都隐藏着一些隐患。正如人们的饮食,少食和暴食都不可取,应当恰到好处。 我们要辨证地看待 C++的新机制,应该恰如其分地使用它们。 虽然这会使我们编程时多 费一些心思,少了一些痛快,但这才是编程的艺术。 阅读全文
posted @ 2018-08-02 12:53 borter 阅读(145) 评论(0) 推荐(0) 编辑
摘要: 用内联取代宏代码 C++ 语言支持函数内联,其目的是为了提高函数的执行效率(速度)。 在 C 程序中,可以用宏代码提高执行效率。宏代码本身不是函数,但使用起来象函 数。预处理器用复制宏代码的方式代替函数调用,省去了参数压栈、生成汇编语言的 CALL 调用、返回参数、执行 return 等过程,从而提 阅读全文
posted @ 2018-08-02 12:51 borter 阅读(215) 评论(0) 推荐(0) 编辑
摘要: 参数的缺省值 有一些参数的值在每次函数调用时都相同,书写这样的语句会使人厌烦。C++语言采 用参数的缺省值使书写变得简洁(在编译时,缺省值由编译器自动插入)。 阅读全文
posted @ 2018-08-02 12:49 borter 阅读(666) 评论(0) 推荐(0) 编辑
摘要: 令人迷惑的隐藏规则 本来仅仅区别重载与覆盖并不算困难,但是 C++的隐藏规则使问题复杂性陡然增加。 这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别与重载混淆)。 阅读全文
posted @ 2018-08-02 12:46 borter 阅读(151) 评论(0) 推荐(0) 编辑
摘要: 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中); (2)函数名字相同; (3)参数不同; (4)virtual 关键字可有可无。 覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类); (2)函数名字相同; (3)参数相同; (4)基类函数必须有 阅读全文
posted @ 2018-08-02 12:45 borter 阅读(124) 评论(0) 推荐(0) 编辑
摘要: 重载是如何实现的? 几个同名的重载函数仍然是不同的函数,它们是如何区分的呢?我们自然想到函数 接口的两个要素:参数与返回值。 如果同名函数的参数不同(包括类型、顺序不同),那么容易区别出它们是不同的函 数。 阅读全文
posted @ 2018-08-02 12:42 borter 阅读(667) 评论(0) 推荐(0) 编辑
摘要: 重载的起源 自然语言中,一个词可以有许多不同的含义,即该词被重载了。人们可以通过上下 文来判断该词到底是哪种含义。 “词的重载”可以使语言更加简练。例如“吃饭”的含义 十分广泛,人们没有必要每次非得说清楚具体吃什么不可。别迂腐得象孔已己,说茴香 豆的茴字有四种写法。 在 C++程序中,可以将语义、功 阅读全文
posted @ 2018-08-02 12:40 borter 阅读(137) 评论(0) 推荐(0) 编辑
摘要: 对比于 C 语言的函数,C++增加了重载(overloaded)、内联(inline)、const 和 virtual 四种新机制。其中重载和内联机制既可用于全局函数也可用于类的成员函数,const 与 virtual 机制仅用于类的成员函数。 重载和内联肯定有其好处才会被 C++语言采纳,但是不可 阅读全文
posted @ 2018-08-02 12:38 borter 阅读(793) 评论(0) 推荐(0) 编辑
摘要: 我认识不少技术不错的 C++/C 程序员,很少有人能拍拍胸脯说通晓指针与内存管理 (包括我自己)。我最初学习 C 语言时特别怕指针,导致我开发第一个应用软件(约 1 万行 C 代码)时没有使用一个指针,全用数组来顶替指针,实在蠢笨得过分。躲避指针 不是办法,后来我改写了这个软件,代码量缩小到原先的一 阅读全文
posted @ 2018-08-02 12:37 borter 阅读(170) 评论(0) 推荐(0) 编辑
摘要: 运算符 new 使用起来要比函数 malloc 简单得多,例如: int *p1 = (int *)malloc(sizeof(int) * length); int *p2 = new int[length]; 这是因为 new 内置了 sizeof、类型转换和类型安全检查功能。 对于非内部数据类 阅读全文
posted @ 2018-08-02 12:35 borter 阅读(146) 评论(0) 推荐(0) 编辑
摘要: 函数 malloc 的原型如下: void * malloc(size_t size); 用 malloc 申请一块长度为 length 的整数类型的内存,程序如下: int *p = (int *) malloc(sizeof(int) * length); 我们应当把注意力集中在两个要素上:“类 阅读全文
posted @ 2018-08-02 12:32 borter 阅读(110) 评论(0) 推荐(0) 编辑
摘要: 内存耗尽怎么办? 如果在申请动态内存时找不到足够大的内存块,malloc 和 new 将返回 NULL 指针, 宣告内存申请失败。通常有三种方式处理“内存耗尽”问题。 阅读全文
posted @ 2018-08-02 12:30 borter 阅读(249) 评论(0) 推荐(0) 编辑
摘要: 有了malloc/free 为什么还要new/delete ? malloc 与 free 是 C++/C 语言的标准库函数,new/delete 是 C++的运算符。它们都可 用于申请动态内存和释放内存。 对于非内部数据类型的对象而言,光用 maloc/free 无法满足动态对象的要求。 对象 在 阅读全文
posted @ 2018-08-02 12:27 borter 阅读(985) 评论(0) 推荐(0) 编辑
摘要: 杜绝“野指针” “野指针”不是 NULL 指针,是指向“垃圾”内存的指针。人们一般不会错用 NULL 指针,因为用 if 语句很容易判断。但是“野指针”是很危险的,if 语句对它不起作用。 阅读全文
posted @ 2018-08-02 12:24 borter 阅读(131) 评论(0) 推荐(0) 编辑
摘要: 动态内存会被自动释放吗? 函数体内的局部变量在函数结束时自动消亡。 p 是局部的指针变量,它消亡的时候会让它所指的动态内存一起完蛋。这是错觉! 阅读全文
posted @ 2018-08-02 12:23 borter 阅读(522) 评论(0) 推荐(0) 编辑
摘要: 别看 free 和 delete 的名字恶狠狠的(尤其是 delete),它们只是把指针所指的内存给 释放掉,但并没有把指针本身干掉。 发现指针 p 被 free 以后其地址仍然不变(非 NULL),只是 该地址对应的内存是垃圾,p 成了“野指针”。如果此时不把 p 设置为 NULL,会让人误 以为 阅读全文
posted @ 2018-08-02 12:19 borter 阅读(167) 评论(0) 推荐(0) 编辑
摘要: 指针参数是如何传递内存的? 如果函数的参数是一个指针,不要指望用该指针去申请动态内存。 阅读全文
posted @ 2018-08-02 12:17 borter 阅读(127) 评论(0) 推荐(0) 编辑
摘要: 指针与数组的对比 C++/C 程序中,指针和数组在不少地方可以相互替换着用,让人产生一种错觉,以 为两者是等价的。 数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而 不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。 指针可以随时指向任意类型的内 阅读全文
posted @ 2018-08-02 12:15 borter 阅读(156) 评论(0) 推荐(0) 编辑
摘要: 常见的内存错误及其对策 发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序 运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。 有时用户怒气冲冲地把你找来,程序却没有发生任何问题,你一走,错误又发作了。 常见的内存错误及其对策如下: 内存分配未成功,却 阅读全文
posted @ 2018-08-02 12:12 borter 阅读(857) 评论(0) 推荐(0) 编辑
摘要: 内存分配方式 内存分配方式有三种: (1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的 整个运行期间都存在。例如全局变量,static 变量。 (2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建 ,函 数执行结束时这些存储单元自动被释放。栈内存分配 阅读全文
posted @ 2018-08-02 12:10 borter 阅读(533) 评论(0) 推荐(0) 编辑
摘要: 内存管理 欢迎进入内存这片雷区。 伟大的 Bill Gates 曾经失言: 640K ought to be enough for everybody — Bill Gates 1981 程序员们经常编写内存管理程序,往往提心吊胆。如果不想触雷,唯一的解决办法 就是发现所有潜伏的地雷并且排除它们,躲 阅读全文
posted @ 2018-08-02 12:07 borter 阅读(100) 评论(0) 推荐(0) 编辑
摘要: 引用与指针的比较 引用是 C++中的概念,初学者容易把引用和指针混淆一起。一下程序中,n 是 m 的一 个引用(reference),m 是被引用物(referent)。 阅读全文
posted @ 2018-08-02 12:05 borter 阅读(86) 评论(0) 推荐(0) 编辑
摘要: 使用断言 程序一般分为 Debug 版本和 Release 版本,Debug 版本用于内部调试,Release 版本 发行给用户使用。 断言 assert 是仅在 Debug 版本起作用的宏,它用于检查“不应该”发生的情况。 一个内存复制函数。 在运行过程中,如果 assert 的参数为假,那么程序 阅读全文
posted @ 2018-08-02 11:57 borter 阅读(111) 评论(0) 推荐(0) 编辑
摘要: 函数内部实现的规则 不同功能的函数其内部实现各不相同,看起来似乎无法就 “内部实现”达成一致的 观点。但根据经验,我们可以在函数体的“入口处”和“出口处”从严把关,从而提高 函数的质量。 阅读全文
posted @ 2018-08-02 11:55 borter 阅读(142) 评论(0) 推荐(0) 编辑
摘要: 函数设计 函数是 C++/C 程序的基本功能单元,其重要性不言而喻。 函数设计的细微缺点很容 易导致该函数被错用,所以光使函数的功能正确是不够的。 本章重点论述函数的接口设 计和内部实现的一些规则。 函数接口的两个要素是参数和返回值。 C 语言中,函数的参数和返回值的传递方式 有两种:值传递(pas 阅读全文
posted @ 2018-08-02 11:53 borter 阅读(124) 评论(0) 推荐(0) 编辑
摘要: 类中的常量 有时我们希望某些常量只在类中有效。由于#define 定义的宏常量是全局的,不能 达到目的,于是想当然地觉得应该用 const 修饰数据成员来实现。const 数据成员的确 是存在的,但其含义却不是我们所期望的。 const 数据成员只在某个对象生存期内是常 量,而对于整个类而言却是可变 阅读全文
posted @ 2018-08-02 11:51 borter 阅读(220) 评论(0) 推荐(0) 编辑
摘要: const 与#define 的比较 C++ 语言可以用 const 来定义常量,也可以用 #define 来定义常量。但是前者比后 者有更多的优点: (1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安 全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替 阅读全文
posted @ 2018-08-02 11:49 borter 阅读(362) 评论(0) 推荐(0) 编辑
摘要: 为什么需要常量 如果不使用常量,直接在程序中填写数字或字符串,将会有什么麻烦? (1) 程序的可读性(可理解性)变差。程序员自己会忘记那些数字或字符串是什么意 思,用户则更加不知它们从何处来、表示什么。 (2) 在程序的很多地方输入同样的数字或字符串,难保不发生书写错误。 (3) 如果要修改数字或字 阅读全文
posted @ 2018-08-02 11:47 borter 阅读(456) 评论(0) 推荐(0) 编辑
摘要: 常量是一种标识符,它的值在运行期间恒定不变。C 语言用 #define 来定义常量(称 为宏常量)。C++ 语言除了 #define 外还可以用 const 来定义常量(称为 const 常量)。 阅读全文
posted @ 2018-08-02 11:46 borter 阅读(185) 评论(0) 推荐(0) 编辑
摘要: goto 语句 自从提倡结构化设计以来,goto 就成了有争议的语句。 首先,由于 goto 语句可以 灵活跳转,如果不加限制,它的确会破坏结构化设计风格。其次,goto 语句经常带来错 误或隐患。 它可能跳过了某些对象的构造、变量的初始化、重要的计算等语句。 阅读全文
posted @ 2018-08-02 11:44 borter 阅读(608) 评论(0) 推荐(0) 编辑
摘要: 循环语句的效率 C++/C 循环语句中,for 语句使用频率最高,while 语句其次,do 语句很少用。本节 重点论述循环体的效率。提高循环体效率的基本办法是降低循环体的复杂性。 阅读全文
posted @ 2018-08-02 11:42 borter 阅读(295) 评论(0) 推荐(0) 编辑
摘要: 复合表达式 如 a = b = c = 0 这样的表达式称为复合表达式。允许复合表达式存在的理由是: (1) 书写简洁; (2)可以提高编译效率。但要防止滥用复合表达式。 阅读全文
posted @ 2018-08-02 11:40 borter 阅读(367) 评论(0) 推荐(0) 编辑
摘要: 表达式和基本语句 读者可能怀疑:连 if、for、while、goto、switch 这样简单的东西也要探讨编程风 格,是不是小题大做? 我真的发觉很多程序员用隐含错误的方式写表达式和基本语句,我自己也犯过类似 的错误。 表达式和语句都属于 C++/C 的短语结构语法。 它们看似简单,但使用时隐患比 阅读全文
posted @ 2018-08-02 11:38 borter 阅读(110) 评论(0) 推荐(0) 编辑
上一页 1 ··· 39 40 41 42 43 44 45 46 47 ··· 50 下一页