统一标点风格

This commit is contained in:
Jerry Lee
2017-07-19 11:57:14 +08:00
parent 4ddaa5fb10
commit 70e8950658

View File

@@ -35,10 +35,10 @@
- [2.2 差的案例](#22-%E5%B7%AE%E7%9A%84%E6%A1%88%E4%BE%8B)
- [2.3 值得斟酌的案例](#23-%E5%80%BC%E5%BE%97%E6%96%9F%E9%85%8C%E7%9A%84%E6%A1%88%E4%BE%8B)
- [3. 基于属性的`API`](#3-%E5%9F%BA%E4%BA%8E%E5%B1%9E%E6%80%A7%E7%9A%84api)
- [4. `C++`细节](#4-c%E7%BB%86%E8%8A%82)
- [4. `C++`相关](#4-c%E7%9B%B8%E5%85%B3)
- [4.1 值 vs. 对象](#41-%E5%80%BC-vs-%E5%AF%B9%E8%B1%A1)
- [4.1.1 指针 vs. 引用](#411-%E6%8C%87%E9%92%88-vs-%E5%BC%95%E7%94%A8)
- [4.1.2 按常量引用传递 vs. 按值传递](#412-%E6%8C%89%E5%B8%B8%E9%87%8F%E5%BC%95%E7%94%A8%E4%BC%A0%E9%80%92-vs-%E6%8C%89%E5%80%BC%E4%BC%A0%E9%80%92)
- [4.1.2 按常量引用传参 vs. 按值传参](#412-%E6%8C%89%E5%B8%B8%E9%87%8F%E5%BC%95%E7%94%A8%E4%BC%A0%E5%8F%82-vs-%E6%8C%89%E5%80%BC%E4%BC%A0%E5%8F%82)
- [4.2 虚函数](#42-%E8%99%9A%E5%87%BD%E6%95%B0)
- [4.2.1 避免虚函数](#421-%E9%81%BF%E5%85%8D%E8%99%9A%E5%87%BD%E6%95%B0)
- [4.2.2 虚函数 vs. 复制](#422-%E8%99%9A%E5%87%BD%E6%95%B0-vs-%E5%A4%8D%E5%88%B6)
@@ -77,7 +77,7 @@
## 1.1 极简
极简的`API`是指每个 class 的 public 成员尽可能少,public 的 class 也尽可能少。这样的`API`更易理解、记忆、调试和变更。
极简的`API`是指每个`class`的`public`成员尽可能少,`public`的`class`也尽可能少。这样的`API`更易理解、记忆、调试和变更。
## 1.2 完备
@@ -107,7 +107,7 @@
静态多态也使记忆`API`和编程模式更加容易。因此,一组相关的类有相似的`API`有时候比每个类都有各自的一套`API`更好。
一般来说,在`Qt`中,如果没有足够的理由要使用继承,我们更倾向于用静态多态。这样可以减少`Qt` public 类的个数,也使刚学习`Qt`的用户在翻看文档时更有方向感。
一般来说,在`Qt`中,如果没有足够的理由要使用继承,我们更倾向于用静态多态。这样可以减少`Qt` `public`类的个数,也使刚学习`Qt`的用户在翻看文档时更有方向感。
## 2.1 好的案例
@@ -202,7 +202,7 @@ color.getHsv(h, s, v);
只有第一行代码清楚表达出`h`、`s`、`v`参数在函数调用中非常有可能会被修改。
这也就是说,编译器并不喜欢“出参”,所你应该在新的API中避免使用“出参”,而是返回一个结构体,如下所示:
这也就是说,编译器并不喜欢『出参』,所你应该在新的API中避免使用『出参』,而是返回一个结构体,如下所示:
```cpp
struct Hsv { int hue, saturation, value };
@@ -235,7 +235,7 @@ void setAlarm(const QSharedPointer<Alarm> &alarm);
// are good examples of other classes you should pass by value.
```
>【译注】:这是传引用和传值的差别了,因为传值会有对像拷贝,传引用则不会。所以,如果对像的构造比较重的话(换句话说,就是对像里的成员变量需要的内存比较大),这就会影响很多性能。所以,为了提高性能,最好是传引用。但是如果传入引用的话,会导致这个对象可能会被改变。所以传入 const reference。
>【译注】:这是传引用和传值的差别了,因为传值会有对像拷贝,传引用则不会。所以,如果对像的构造比较重的话(换句话说,就是对像里的成员变量需要的内存比较大),这就会影响很多性能。所以,为了提高性能,最好是传引用。但是如果传入引用的话,会导致这个对象可能会被改变。所以传入`const reference`。
## 4.2 虚函数
@@ -258,7 +258,7 @@ virtual void setOverwriteMode( bool b ) { overWrite = b; }
`QTextEdit`从`Qt 3`移植到`Qt 4`的时候,几乎所有的虚函数都被移除了。有趣的是(但在预料之中),并没有人对此有大的抱怨,为什么?因为`Qt 3`没用到`QTextEdit`的多态行为 —— 只有你会;简单地说,没有理由去继承`QTextEdit`并重新实现这些函数,除非你自己调用了这些方法。如果在`Qt`在外部你的应用程序你需要多态,你可以自己添加多态。
> 【译注】:“多态”的目的只不过是为了实践——“依赖于接口而不是实现”,也就是说,接口是代码抽像的一个非常重要的方式(在Java/Go中都有专的接口声明的语法)。所以,如果没有接口抽像,使用“多态”的意义也就不大了,因为也就没有必要使用“虚函数”了。
> 【译注】:『多态』的目的只不过是为了实践 —— 『依赖于接口而不是实现』,也就是说,接口是代码抽像的一个非常重要的方式(在`Java/Go`中都有专的接口声明的语法)。所以,如果没有接口抽像,使用『多态』的意义也就不大了,因为也就没有必要使用『虚函数』了。
### 4.2.1 避免虚函数
@@ -275,13 +275,13 @@ virtual void setOverwriteMode( bool b ) { overWrite = b; }
- 重载虚函数并不容易
- 编译器几乎不能优化或内联(`inline`)对虚函数的调用
- 虚函数调用需要查找虚函数表(`v-table`),这比普通函数调用慢了2到3倍
- 虚函数使得类很难按值复制(尽管可也按值复制,但是非常混乱并且不建议这样做)
- 虚函数使得类很难按值复制(尽管也可以按值复制,但是非常混乱并且不建议这样做)
经验告诉我们,没有虚函数的类一般`bug`更少、维护成本也更低。
一般的经验法则是,除非我们以这个类作为工具集提供而且有很多用户来调用某个类的虚函数,否则这个函数九成不应该设计成虚函数。
>【译注】:1)使用虚函数时,你需要对编译器的内部行为非常清楚,否则,你会在使用虚函数时,觉得有好些“古怪”的问题发生。2)在C++中,会有一个基础类,这个基础类中已经实现好了很多功能,然后把其中的一些函数放给子类去修改和实现。这种方法在父类和子类都是一组开发人员维护时没有什么问题,但是如果这是两组开发人员,这就会带来很多问题了,就像Qt这样,子类完全无法控制,全世界的开发人员想干什么就干什么。所以,子类的代码和父类的代码在兼容上就会出现很多很多问题。所以,还是上面所说,其实,虚函数应该声明在接口的语义里(这就是设计模式的两个宗旨——依赖于接口,而不是实现;钟爱于组合,而不是继承)
>【译注】:1) 使用虚函数时,你需要对编译器的内部行为非常清楚,否则,你会在使用虚函数时,觉得有好些『古怪』的问题发生。2) 在`C++`中,会有一个基础类,这个基础类中已经实现好了很多功能,然后把其中的一些函数放给子类去修改和实现。这种方法在父类和子类都是一组开发人员维护时没有什么问题,但是如果这是两组开发人员,这就会带来很多问题了,就像`Qt`这样,子类完全无法控制,全世界的开发人员想干什么就干什么。所以,子类的代码和父类的代码在兼容上就会出现很多很多问题。所以,还是上面所说,其实,虚函数应该声明在接口的语义里(这就是设计模式的两个宗旨——依赖于接口,而不是实现;钟爱于组合,而不是继承)
### 4.2.2 虚函数 vs. 复制
@@ -406,7 +406,7 @@ int main() {
}
```
> 【译注】:上述的代码说明,如果返回值不是 const 的,代码可以顺利编译通过,然后并没有什么卵用,因为那个临时对像马上就被抛弃了。所以,这样的无用的代码最好还是在编译时报个错,以免当时头脑发热想错了。
> 【译注】:上述的代码说明,如果返回值不是`const`的,代码可以顺利编译通过,然后并没有什么卵用,因为那个临时对像马上就被抛弃了。所以,这样的无用的代码最好还是在编译时报个错,以免当时头脑发热想错了。
### 4.3.3 返回值:非`const`的指针还是有`const`的指针
@@ -446,7 +446,7 @@ foreach (const QGraphicsItem *item, scene.items()) {
(以`d-point`的典型做法(`idiom`)为例,我们可以在任何时候改变`Qt`类在内存表示(`memory representation`);但却不能在不破坏二进制兼容性的情况下把改变函数的签名,返回值从`const QFoo &`变为`QFoo`。)
基于这个原因,除去对运行速度敏感(`speed is critical`)而重构不是问题的个别情形(例如,`QList::at()`),我们一般返回`QFoo`而不是`const QFoo &`。
> 【译注】:《Effective C++》中条款23:Don't try to return a reference when you must return an object
> 【译注】:《Effective C++》中条款23:Don't try to return a reference when you must return an object.
### 4.4.5 `const` vs. 对象的状态
@@ -512,7 +512,7 @@ void QGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem opti
当你找不到好的名称时,开始写文档是一种好好的寻找方式:尝试为类、方法、枚举类型、值等写文档,把写下的第一句作为启发。如果找不确切的名称,这说明这个东西不该存在。如果所有尝试都失败了,并且你认为不如发明一个新名称,你就知道`widget`,`event focus`和`buddy`是如何产生的了。
> 【译注】:写文档是一个非常好的习惯。写文档的过程其实就是在帮你梳理你的编程思路。很多时候,写着写文档你就会发现,你要去改代码去了。除了上述的好处多,写文档还有更多的好处。比如,在写文档的过程中,你发现文字描述过于复杂了,这表明着你的代码或逻辑是复杂的,这就倒逼你去重构你的代码。所以——**写文档其实就是写代码**。
> 【译注】:写文档是一个非常好的习惯。写文档的过程其实就是在帮你梳理你的编程思路。很多时候,写着写文档你就会发现,你要去改代码去了。除了上述的好处多,写文档还有更多的好处。比如,在写文档的过程中,你发现文字描述过于复杂了,这表明着你的代码或逻辑是复杂的,这就倒逼你去重构你的代码。所以 —— **写文档其实就是写代码**。
## 6.2 类的命名
@@ -616,7 +616,7 @@ slider->setValue(13);
slider->setObjectName("volume");
```
>【译注】:在有 IDE 的自动提示的支持下,后者写起来非常方便,而前者还需要看相应的文档。
>【译注】:在有`IDE`的自动提示的支持下,后者写起来非常方便,而前者还需要看相应的文档。
## 7.2 `Boolean`参数的陷阱