文档章节

[C++ 学习笔记 11] Effective C++ 条款 18-25

UMU
 UMU
发布于 2017/03/03 11:18
字数 1483
阅读 24
收藏 0

第四章 设计与声明

18、让接口容易被正确使用,不易被误用

    “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容。一致性的例子:STL 容器都有 size 成员函数。不一致性对开发人员造成的心理负担,没有任何一个 IDE 可以完全抹除。

    “阻止误用”的办法包括建立新类型、限制类型上的操作,束缚对象值,以及消除客户的资源管理责任。

    std::shared_ptr 使用每个指针专属的删除器,消除“cross-DLL problem”;它还支持定制删除器,可被用来自动解除互斥锁(mutexes,见条款 14,https://my.oschina.net/umu618/blog/839649)。

19、设计 class 犹如设计 type

    Class 设计就是 type 的设计,在定义一个新 type 之前,要考虑以下主题:

(1)新 type 的对象应该如何被创建和销毁?

(2)对象的初始化和赋值该有什么差别?

(3)新 type 的对象如果被以值传递(pass by value),意味着什么?

(4)什么的新 type 的合法值?setter 函数要检查错误。

(5)新 type 需要配合某个继承图系(inheritance graph)吗?这影响函数——尤其是析构函数,是否为 virtual(见条款 7,https://my.oschina.net/umu618/blog/831411)。

(6)新 type 需要什么样的转换?如果希望 T1 被隐式转换为 T2,必须在 class T1 内写一个类型转换函数(operator T2)或在 class T2 内写一个可被单一实参调用(non-explicit-one-argument)的构造函数。如果只允许 explicit 构造函数存在,就得写出专门负责转换的函数,且不得为类型转换操作符(type conversion perators)或 non-explicit-one-argument 构造函数。(条款 15 有隐式和显式转换函数的范例,https://my.oschina.net/umu618/blog/839649

(7)什么样的操作符和函数对此新 type 而言是合理的?这决定你的 class 有哪些函数,其中哪些是 member 函数,哪些则否。(参考条款 23, 24, 26)

(8)什么样的标准函数应该驳回?声明为 private。(见条款 6,https://my.oschina.net/umu618/blog/831411

(9)谁该取用新 type 的成员?这个问题帮你决定成员的可见性(public、protected、private)。也帮你决定哪个 classes 和/或 functions 应该是 friends,以及将它们嵌套于另一个之内是否合理。

(10)什么是新 type 的未声明接口(undeclared interface)?它对效率、异常安全性(见条款 29)以及资源运用(例如多任务锁定和动态内存)提供何种保证?你在这些方面提供的保证,将为你的 class 实现代码加上相应的约束条件。

(11)新 type 有多么一般化?new class or new class template?

(12)真的需要一个新 type 吗?如果只是定义新的子类(derived class)以便为既有 class 添加机能,那么也许单纯定义一或多个 non-member 函数或

20、宁以 pass-by-reference-to-const 替换 pass-by-value

    尽量以 pass-by-reference-to-const 替换 pass-by-value。前者通常比较高效,并可避免切割问题(slicing problem,即派生类被转化成基类时丢失派生类特有的成分)。

    以上规则并不适用于内置类型,以及 STL 的迭代器和函数对象。对它们而言,pass-by-value 往往比较适当。

21、必须返回对象时,别妄想返回其 reference

    不要返回 pointer 或 reference 指向一个 local stack 对象,因为离开作用域即被销毁。

    不要返回 reference 指向一个 heap-allocated 对象,因为无法保证配套 delete。

    不要返回 pointer 或 reference 指向一个 local static 对象而有可能同时需要多个这样的对象。

#include <stdio.h>

#define _WINSOCK_DEPRECATED_NO_WARNINGS // to use inet_ntoa
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

int main()
{
    in_addr a1 = {1, 2, 3, 4};
    in_addr a2 = {5, 6, 7, 8};
    printf_s("You think it's: %s, ", inet_ntoa(a1));
    printf_s("%s\n", inet_ntoa(a2));
    printf_s("But in fact it's: %s, %s\n", inet_ntoa(a1), inet_ntoa(a2));
    return 0;
}

    以上代码输出为:

You think it's: 1.2.3.4, 5.6.7.8
But in fact it's: 1.2.3.4, 1.2.3.4

22、将成员变量声明为 private

    切记将成员变量声明为 private。这可赋予客户访问数据的一致性、可细微划分访问控制、允诺约束条件获得保证,并提供 class 作者以充分的实现弹性。

    protected 并不比 public 更具封装型。

23、宁以 non-member、non-friend 替换 member 函数

    宁可拿 non-member non-friend 函数替换 member 函数。这样做可以增加封装型、包裹弹性(packaging flexibility)和技能扩充性。

24、若所有参数皆需类型转换,请为此采用 non-member 函数

    member 函数的反面是 non-member 函数,而不是 friend 函数。

    设计 operator * 时,要能支持乘法交换律。

    如果你需要为某个函数的所有参数(包括 this 指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个 non-member。从 Object-Oriented C++ 跨进 Template C++ 时,会有新争议和解法,参考条款 46。

25、考虑写出一个不抛异常的 swap 函数

    通常我们不能改变 std 命名空间内的任何东西,但可以为 temlates 制造特化版本。

    C++ 只允许对 class templates 偏特化(partially specialize),而对 function templates 则不许。

    当 std::swap 对你的类型效率不高时,提供一个 swap 成员函数,并确定这个函数不抛出异常。因为成员 swap 的一个最好应用是帮助 classes 和 class templates 提供强烈的异常安全性(exception-safety)保障。条款 29 细说。

    如果你提供了一个 member swap,也该提供一个 non-member swap 用来条用前者。对于 classes(而非 templates),也请特化 std::swap。

    调用 swap 时应针对 std::swap 使用 using 声明式,然后调用 swap 并不带任何“命名空间资格修饰”。

    为“用户定义类型”进行 std templates 全特化是好的,但千万不要尝试在 std 内加入某些对 std er

© 著作权归作者所有

UMU

UMU

粉丝 119
博文 112
码字总数 44043
作品 0
厦门
程序员
私信 提问
学习C++的50条,谨以送给C++的粉丝们

1.把C++当成一门新的语言学习(和C没啥关系!真的);   2.看《Thinking In C++》,不要看《C++变成死相》(C++编程思想,翻译的非常差);   3.看《The C++ Programming Language》(这...

地瓜儿
2013/01/11
1K
7
C++ 书籍大汇

C++ 书籍大汇 C++ 书籍大汇 语言基础入门: 1. C++ Primer 《C++入门》(通常不用中文名) by Stanley B. Lippman 有第三版和第四版,如其名,是C++入门的不二选择,是全面广泛的参考书目,内...

长平狐
2012/09/20
284
0
Effective C++ 笔记(1):视C++为语言联邦

条款一(clause 1) 将C++视为语言联邦:提出了一种将C++分为四种不同次语言的观念,四种次语言分别是: 1、C语言,面向过程的语言,C++完全向下兼容C,在C++中单纯使用C语言的语法除了遵守的一...

oldpan
2017/09/10
0
0
【2018.08.13 C与C++基础】C++语言的设计与演化读书笔记

先占坑 老实说看这本书的时候,有很多地方都很迷糊,但却说不清楚问题到底在哪里,只能和Effective C++联系起来,更深层次的东西就想不到了。 链接: https://blog.csdn.net/cloudqiu/artic...

waitingdeng
2018/08/21
0
0
C++各阶段学习书目

1. 入门 Lippman的《Essential C++》 顾名思义,这本书是很短小精悍的。通过这本书,可以对C++的最常用和重要的特性有全面的了解,并对C++的全貌有一个概念。虽然这远远不够,但就是这样的书...

晨曦之光
2012/04/24
429
1

没有更多内容

加载失败,请刷新页面

加载更多

Taro 兼容 h5 踩坑指南

最近一周在改造 公羊阅读🐏 Taro 版本适配 h5 端,过程中改改补补,好不酸爽。 本文记录📝遇到的问题,希望为有相同需求的哥们👬节约点时间。 Taro 版本:1.3.9。 client_mobile_taro...

dkvirus
今天
4
0
Spring boot 静态资源访问

0. 两个配置 spring.mvc.static-path-patternspring.resources.static-locations 1. application中需要先行的两个配置项 1.1 spring.mvc.static-path-pattern 这个配置项是告诉springboo......

moon888
今天
3
0
hash slot(虚拟桶)

在分布式集群中,如何保证相同请求落到相同的机器上,并且后面的集群机器可以尽可能的均分请求,并且当扩容或down机的情况下能对原有集群影响最小。 round robin算法:是把数据mod后直接映射...

李朝强
今天
4
0
Kafka 原理和实战

本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/bV8AhqAjQp4a_iXRfobkCQ 作者简介:郑志彬,毕业于华南理工大学计算机科学与技术(双语班)。先后从事过电子商务、开放平...

vivo互联网技术
今天
19
0
java数据类型

基本类型: 整型:Byte,short,int,long 浮点型:float,double 字符型:char 布尔型:boolean 引用类型: 类类型: 接口类型: 数组类型: Byte 1字节 八位 -128 -------- 127 short 2字节...

audience_1
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部