⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1005.html

📁 著名的linux英雄站点的文档打包
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<br>
3.1.2  原因<br>
<br>
先声明使得编译器能够在编译时就检查和找出错误(而不是等到连接或运行时)。<br>
<br>
正文P40原则3.17  当函数返回引用或指针时,用文字描述其有效期<br>
<br>
3.17.1  说明<br>
<br>
有效期是指引用或指针能有效地找到对象的期间。文字描述最好以注释形式放在函数所在的头文件中(这样比较直接)。<br>
<br>
更改为<br>
<br>
3.17.1  说明<br>
<br>
有效期是指引用或指针能有效地找到目标的时间段。文字描述最好以注释形式放在函数所在的头文件中(这样比较直接)。<br>
<br>
正文P41<br>
<br>
3.18.2  原因<br>
<br>
……<br>
<br>
返回只读(常量)的引用或指针还是可接受的。<br>
<br>
更改为<br>
<br>
关于能否返回只读(常量)的引用或指针,请参见“原则8.3  类成员可以转换成常量形式暴露出来”。<br>
<br>
正文P41~42<br>
<br>
3.20.1  说明<br>
<br>
如果我们能把友元函数定义成虚函数,则子类既可以继承该友元的接口而无需重复声明友元……<br>
<br>
更改为<br>
<br>
如果我们能把友元函数定义成虚函数,则子类既可以继承该函数而无需重复声明友元……<br>
<br>
正文P45原则4.2  类成员应是私有的(private)<br>
<br>
4.2.2  原因<br>
<br>
更糟的是,任何对类的修改都将影响使用该类的代码,因为这些代码有权直接访问(被修改的)类成员。<br>
<br>
更改为<br>
<br>
更糟的是,任何对类实现的修改都可能影响使用该类的代码,因为这些代码有权直接访问(被修改的)类成员。<br>
<br>
正文p47原则4.5  降低类间的耦合度<br>
<br>
4.5.2  例子<br>
<br>
经常看到这样的例子:一个大功能模块中有许多不同类型的对象,为了协同工作,每类对象都多少带有其他对象的指针或引用,造成你中有我,我中有你,最终导致一锅粥,谁也离不开谁。<br>
<br>
更改为<br>
<br>
4.5.2  例子<br>
<br>
经常看到这样的例子:一个大功能模块中有许多不同类型的对象,为了协同工作,每类对象内部都多少带有其他对象的指针或引用,造成你中有我,我中有你,最终导致一锅粥,谁也离不开谁。<br>
<br>
正文p50原则4.9  避免为每个类成员提供访问函数<br>
<br>
原因<br>
<br>
……<br>
<br>
专注于属性的类在多线程环境下效率低下。若专注于行为,一次行为会修改一连串相关属性而只需上一次锁(在一个成员函数/行为中);而专注于属性,则不得不每修改一个属性就上一次锁(在每个类成员提供访问函数中),因为要防止多个线程同时调用访问函数(去修改同一个属性)。<br>
<br>
更改为<br>
<br>
……<br>
<br>
专注于属性的类在多线程环境下效率低下。若专注于行为,一次行为会修改一连串相关属性而只需上一次锁(在一个成员函数中);而专注于属性,则不得不每修改一个属性就上一次锁(在每个类成员的访问函数中),因为要防止多个线程同时调用访问函数(去修改同一个属性)。<br>
<br>
正文p54<br>
<br>
原则4.16  用嵌套类的方法减少匿名命名空间类的数量<br>
<br>
4.16.1  说明<br>
<br>
不需要把所有类的定义都放在匿名命名空间中。嵌套在别的类中的类是不属于匿名命名空间的。<br>
<br>
更改为<br>
<br>
原则4.16  用嵌套类的方法减少全局命名空间类的数量<br>
<br>
4.16.1  说明<br>
<br>
不需要把所有类的定义都放在全局命名空间中。嵌套在别的类中的类是不属于全局命名空间的。<br>
<br>
 <br>
<br>
正文p55<br>
<br>
第5章  (面向对象的)继承<br>
<br>
继承是面向对象语言的一个基本特性。这是一个强大的功能,但必须运用得当,否则发挥不出其特点,甚至适得其反。<br>
<br>
更改为<br>
<br>
继承是面向对象语言的一个基本特性。功能强大自不必多言,但“打破封装”的副作用却鲜为人知,所以必须运用得当,否则发挥不出其特点,甚至适得其反。<br>
<br>
正文p55原则5.2  关于“有”和“由…实现”<br>
<br>
5.2.1  说明<br>
<br>
(一个类)包含(另一个类)意味着“有一个”或“由…实现”。“私有继承(private inheritance)”意味着“由…实现”。<br>
<br>
更改为<br>
<br>
5.2.1  说明<br>
<br>
(一个类)包含(另一个类)意味着“有一个”或“由…实现”。“私有继承(private inheritance)”意味着“由…实现”(和“包含”类似;完全不同于“公共继承”)。<br>
<br>
正文p59<br>
<br>
5.5.2  原因<br>
<br>
……<br>
<br>
与此类似,同层类的个数也不能太多,否则应考虑是否要加一个父类,以便做某种程度上的(新的)抽象,从而减少同层类的个数(这是一种平衡的艺术)。<br>
<br>
更改为<br>
<br>
与此类似,派生于同一父类的子类个数也不能太多(计划生育?),否则应考虑是否要加一层父类,通过某种程度上的(新的)抽象,减少同层类的个数(这是一种平衡的艺术)。<br>
<br>
正文p59<br>
<br>
原则5.6  继承树上非叶子节点的类应是虚基类<br>
<br>
5.6.1  例子<br>
<br>
如果你有两个(非虚)类C1和C2,且希望C2派生于C1,如图5-1左边所示,则应该增加一个虚基类A,且将C1和C2都从A派生出来,如图5-1右边所示。<br>
<br>
更改为<br>
<br>
原则5.6  继承树上非叶子节点的类应是抽象基类<br>
<br>
5.6.1  例子<br>
<br>
如果你有两个(非抽象)类C1和C2,且希望C2派生于C1,如图5-1左边所示,则应该增加一个抽象基类(abstract base class)A,且将C1和C2都从A派生出来,如图5-1右边所示。<br>
<br>
正文p60<br>
<br>
……<br>
<br>
进一步说,因为C++的类封装了具体实现,而只把接口露在外面,所以C1的接口应该是C2最想要继承的。换句话说,只要C2继承了C1的接口,C2的对象就可以被看作C1的对象而参与任何C1对象可参与的活动。由此可见,接口本身(而不是具体实现)是参与活动的充分必要条件,这就是为什么A通常是虚基类。<br>
<br>
让我们再换一个角度,继承的一大缺点是打破封装,即把基类的实现细节暴露给派生类。导致的结果是,对基类的修改将无法保证不会波及派生类,即基类和派生类是紧耦合关系(紧耦合的缺点请参见“原则4.5  降低类间的耦合度”),除非基类是纯虚的(没有实现细节)。<br>
<br>
另外,为了防止多重继承带来的各种问题(参见“原则5.14  慎用多重继承”),也建议继承树上非叶子节点的类尽量是没有成员的纯虚基类(类似于Java中的Interface)。<br>
<br>
更改为<br>
<br>
进一步说,因为C++的类封装了具体实现,而只把接口露在外面,所以C1的接口应该是C2最想要继承的。换句话说,只要C2继承了C1的接口,C2的对象就可以被看作C1的对象而参与任何C1对象可参与的活动。由此可见,接口本身(而不是具体实现)是参与活动的充分必要条件,这就是为什么A通常是只定义接口的完全的抽象基类(类似于Java中的Interface)。<br>
<br>
用完全抽象基类的另一个原因:继承存在一个很大的缺陷,就是打破封装,即把基类的实现细节暴露给派生类。导致的结果是,对基类的修改将无法保证不会波及派生类,即基类和派生类是紧耦合关系(紧耦合的缺点请参见“原则4.5  降低类间的耦合度”),除非基类完全没有实现细节。<br>
<br>
用完全抽象基类的第三个原因:为了防止多重继承带来的各种问题(参见“原则5.14  慎用多重继承”),继承树上非叶子节点的类最好没有成员。<br>
<br>
正文p73<br>
<br>
6.8.3  原因<br>
<br>
防止其后再次使用该指针。<br>
<br>
更改为<br>
<br>
防止其后再次使用该指针(使用NULL会立刻导致系统错误,好查)。<br>
<br>
正文p85原则7.19  将循环索引的初值定在循环点附近<br>
<br>
7.19.1  例子<br>
<br>
假设循环队列下标从0到MAX-1(MAX为该队列可容纳的元素个数),则队首应设在MAX-3处。<br>
<br>
7.19.2  原因<br>
<br>
循环索引最常出问题的地方就在循环点附近,将队首放在这里可以很早就发现问题。<br>
<br>
问题常出现在:插入元素使得下标从MAX-1绕回到0、删除元素使得下标从0绕回到MAX-1、插入头一两个元素,以及删除最后一两个元素时。选择MAX-3可以一口气将这些情况都覆盖住。<br>
<br>
更改为<br>
<br>
7.19.1  例子<br>
<br>
假设循环队列下标从0到MAX-1(MAX为该队列可容纳的元素个数),则队首游标应设在MAX-3处。<br>
<br>
7.19.2  原因<br>
<br>
循环索引最常出问题的地方就在循环点附近,将队首游标放在这里可以很早就发现问题。<br>
<br>
问题常出现在:插入元素使得游标从MAX-1绕回到0、删除元素使得游标从0绕回到MAX-1、插入头一两个元素,以及删除最后一两个元素时。选择MAX-3可以一口气将这些情况都覆盖住。<br>
<br>
正文p89<br>
<br>
原则8.1  关于常量修饰符的含义<br>
<br>
例子<br>
<br>
char* p = “Hello.”;             // 指针不是常量,指针指向的也不是常量<br>
<br>
const char* p = “Hello.”;       // 指针不是常量,指针指向的是常量<br>
<br>
char* const p = “Hello.”;       // 指针是常量,指针指向的不是常量<br>
<br>
const char* const p = “Hello”;  // 指针是常量,指针指向的也是常量<br>
<br>
更改为<br>
<br>
原则8.1  关于常量修饰符的含义<br>
<br>
8.1.1  例子<br>
<br>
char* p = “Hello.”;             // 指针不是常量,指针指向的也不是常量<br>
<br>
char const* p = “Hello.”;       // 指针不是常量,指针指向的是常量<br>
<br>
char* const p = “Hello.”;       // 指针是常量,指针指向的不是常量<br>
<br>
char const* const p = “Hello”;  // 指针是常量,指针指向的也是常量<br>
<br>
8.1.2  说明<br>
<br>
“char* p”的意思是:p是一个指针;它指向字符类型。<br>
<br>
“char const* p”的意思是:p是一个指针;它指向一个常量;该常量是字符类型。<br>
<br>
“char* const p”的意思是:p是一个常量;它是一个指针常量;该常量指针指向字符类型。<br>
<br>
“char const* const p”的意思是:p是一个常量;它是一个指针常量;该常量指针指向一个常量;而被指向的常量是字符类型。<br>
<br>
正文p89~90<br>
<br>
8.2.3  原因<br>
<br>
编译器会永远记住此事。如果今后对blockCopy()的任何修改(有意或无意)要对pSrc所指数据进行写操作,就会引起编译错误,从而提示该函数的后继开发者遵循最初的设计。<br>
<br>
更改为<br>
<br>
编译器会永远记住此事。如果今后对blockCopy()函数体的任何修改(有意或无意)要对pSrc所指数据进行写操作,就会引起编译错误,从而提示该函数的后继开发者遵循最初的设计。<br>
<br>
正文p92<br>
<br>
8.5.2  原因<br>
<br>
造成程序状态改变的成员函数不是绝对意义上的常量成员函数(不符合大多数人对常量成员函数的预期)。<br>
<br>
更改为<br>
<br>
造成程序状态改变的成员函数不是绝对意义上的常量成员函数。虽然不一定违反C++语法,但语义有问题,且不符合大多数人对常量成员函数的预期。<br>
<br>
 <br>
<br>
正文p123原则15.4  不要用分号结束宏定义<br>
<br>
例子<br>
<br>
/*<br>
<br>
* 用分号结尾,结果导致下面第二条语句变成<br>
<br>
* “channel=CHANNEL_MAX;-1;”,编译出错<br>
<br>
*/<br>
<br>
更改为<br>
<br>
例子<br>
<br>
/*----------------------------------------<br>
<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -