【复读EffectiveC++19】条款19:设计 class 犹如设计 type

条款19:设计 class 犹如设计 type

在看到”class”和”type”,就一定要先区别一下这两者:
class - 其意思是自定义的类,需要自己控制一切;
type - 其意思是系统预定义的类,类似int、double、string、vector,别人写好给大家用的。

因此,此条款就是在强调,自定义的类要参考系统预设的类,看看别人的类是怎么写的,它是为什么好用,为什么安全的,这对设计思想提出了较高的要求。

原书中也给出了一些基础性的参考问题,如下:

一、需要回答的问题

1、对象如何去创建和销毁?

这里个人觉得是要考虑构造函数和析构函数内要做什么,比如考虑性能就要记得处理指针成员变量,是否要在构造就去new,析构要不要处理delete等。
详见 第八章 的设计思路。

2、对象初始化与对象的赋值应该有什么样的差别?

切莫混淆 “初始化” 和 “赋值”。
详见 第四章 的设计思路

3、新type如果被pass-by-value意味着什么?

此问题关注点在于拷贝构造函数,要注意区分 浅拷贝深拷贝 ,进而根据情况进行选择。

4、什么是新type的合法值?

合法值,最初只是以为是要考虑数值的约束范围,就像 第十八章 中所讲,后来发现还需要考虑约束范围不清楚的情况下,抛出异常了要怎么处理,虽然并不常见。

5、你的新type需要配合某个继承图系吗?

考虑配合继承图系的时候,要注意两种情况:
a、要继承已有类,就天然受到被继承类的限制约束,比如那些需要重写,那些需要重载等等;
b、可能被后续类继承,就要本类的拓展,哪些是图系不需要更改的重要特征,哪些是后续可以自定义的部分,甚至是必须自定义;
这部分要深挖,其实可以结合设计模式。

6、新type需要什么样的转换?

主要是针对隐式转换,operator OtherType() const,但通常情况下隐式转换也意味着隐患,所以设计时要谨慎。另外,构造函数中也要当心,如果不想让隐式构造发生,就要在前面加上explicit关键字。举个例子:

class A
{
private:
         int a;
public:
         A(int b):a(b){}
};
void fun(A obj);

若调用fun(3),则编译器也能接受,因为编译器自动作了fun(A(3))的处理,这就是隐式构造。而如果用户自己写fun(A(3)),这是显式构造。当A的构造函数前有explicit时,fun(3)的调用将通不过编译器。通常情况下,隐式转换是安全的。

7、什么样的操作符和函数对此新type而言是合理的?

就是设计什么样的成员函数,以及重载哪些运算符。

8、 什么样的标准函数应该驳回?

这一条就是在针对 private , public 和 protected三兄弟,前两者在普通类中相当常见,就是用来处理那些可以直接而自由的访问,那些必须用间接而带有限制的访问,这些都是基本功;
而protected是有继承关系的类中使用的,也可以说是一个进阶的方向。
详见 第六章 的设计思路。

9、 谁该取用新type成员?

与上面一条类似,但这一条正偏向于自定义类中的成员函数,比如有些成员函数不可以自由修改,就要用private ,然后用get, set方法来限制性的使用;

10、 什么是新type的未声明接口?

个人对这条的理解暂时是,因为c++是.h文件声明,.cpp文件实现的,因此,有些函数是可以不放在.h文件中声明,进而防止被包含这个.h文件的类使用的,要学会分析情况,灵活使用这种方法,也要注意出现的异常等问题。

11、 你的新type有多么一般化?

这牵涉到泛型编程了,也就是模板,可以参考STL各种容器的实现,体会泛型的强大。

12、 你真的需要一个新type吗?

请把这一条放在最前面,先去考虑自使用定义类达成的目标,是否可以用更简单的结构来达成,比如一个模板。

二、总结

Class 的设计就是 type 的设计。在定义一个新的 type 之前,请确定你已经考虑过本条款覆盖的所有讨论主题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值