C++编程规范 函数与操作符

来源:互联网 发布:山西 软件开发水平 编辑:程序博客网 时间:2024/05/29 14:37

第25条 正确地选择通过值、(智能)指针或者引用传递参数
正确选择参数:分清输入参数、输出参数和输入/输出参数,分清值参数和引用参数。正确地传递参数。
详细:
1、对于只输入参数:始终用 const 限制所有指向只输入参数的指针和引用;优先通过值来取得原始(如 char、float)和复制开销比较低的值对象(如 Point、complex<float>)的输入;优先按 const 的引用取得其他用户定义类型的输入;如果函数需要其参数的副本,则可以考虑通过值传递代替通过引用传递。
2、对于输出参数或者输入/输出参数:如果参数是可选的(这样调用者可以传递 null 表示“不适用的”或“无需关心的”值),或者函数需要保存这个指针的副本或者操控参数的所有权,那么应该优先通过(智能)指针传递;如果参数是必须的,而且函数无需保存指向参数的指针,或者无需操控其所有权,那么应该优先通过引用传递。
3、不要使用 C 语言风格的可变长参数(见 C98)。

第26条 保持重载操作符的自然语义
程序员讨厌意外情况:只在有充分理由时才重载操作符,而且应该保持其自然语义;如果做到这一点很困难,那么你可能已经误用了操作符重载。
详细:
1、在模糊或者违反直觉的情况下,应该使用命名函数。
2、对于值类型:“如果有疑问,就按 int 类型那样去操作。”
3、程序言通常希望操作符成组出现。有 a @ b,那么 b @ a 可以吗?a @= b 呢?逆操作(+ 和 -;* 和 /)呢?

第27条 优先使用算术操作符和赋值操作符的标准形式
如果要定义 a + b,也应该定义 a += b:在定义二元算术操作符时,也应该提供操作符的赋值形式,并且应该尽量减少重复,提高效率。
详细:
1、一般使用如下方式定义:

T & T::operator@=(const T &){// ...... 具体的实现代码 ......return *this;}T operator@(const T &left, const T &right){T result(left);return result @= right;}
2、如果可能,可以将 operator@= 也设为非成员函数(见 C44)。并把非成员操作符放入 T 的同一个名字空间下(见 C57)。
T & operator@=(T &left, const T &right){// ...... 具体的实现代码 ......return left;}T operator@(T left, const T &right){return left @= right;}
3、在一些情况下(比如复数的 operator*=),可能用 operator* 实现 operator*= 比反过来更有利。

第28条 优先使用 ++ 和 -- 的标准形式。优先调用前缀形式
如果定义 ++c,也要定义 c++:递增和递减操作符很麻烦,因为它们都有前缀和后缀形式,而两种形式语义又略有不同。定义 operator++ 和 operator-- 时,应该模仿它们对应的内置操作符。如果不需要原值,应该优先调用前缀版本。
详细:
1、前缀形式如下:
T & T::operator++(){// 执行递增return *this;}T & T::operator--(){// 执行递减return *this;}
2、后缀形式如下:
T T::operator++(int){T old(*this);++*this;return old;}T T::operator--(int){T old(*this);--*this;return old;}
3、这不是不成熟的优化,这是在避免不成熟的劣化(见 C9)。

第29条 考虑重载以避免隐含类型转换
如无必要勿增对象(奥卡姆剃刀原理(即“大道至简”)):隐式类型转换提供了语法上的便利(但另见 C40)。但是如果创建临时对象的工作并不必要而且适合于优化(见 C8),那么可以提供签名与常见参数类型精确匹配的重载函数,而且不会导致转换。
详细:
1、即定义重载以避免隐式转换,重载通常都使用相同的后端函数,类似如下:
bool operator==(const String &left, const String &right);bool operator==(const String &left, const char *right);bool operator==(const char *left, const String &right);

第30条 避免重载 &&、|| 或 ,(逗号)
明智就是知道何时应该适可而止:内置的 &&、|| 或 ,(逗号)得到了编译器的特殊照顾。如果重载它们,它们就会变成普通函数,具有完全不同的语义(这将违反 C26 和 C31),这肯定会引入微妙的错误和缺陷。不要轻率地重载这些操作符。
详细:
1、&& 和 || 使用短路求值,重载无法实现。
2、,(逗号)需要保证从左到右求值,参数求值的顺序是任意的。
3、表达式模板库是一个例外,设计它的目的就是用来捕获所有操作符。

第31条 不要编写依赖于函数参数求值顺序的代码
保持(求值)顺序:函数参数的求值顺序是不确定的,因此不要依赖具体的顺序。
详细:
1、这种问题解决起来其实很简单——使用命名对象控制求值顺序(见 C13)。

返回 目录

返回《C++ 编程规范及惯用法》

原创粉丝点击