Effective C++ 剖析(条款10~22)
目录
条款10 令operator= 返回一个 reference to *this
条款11 在operator= 中处理“自我赋值”
条款12 复制对象时不要忘了其每一个成分
条款13 以对象管理资源
条款14 条款15 条款17(历史问题,直接用智能指针就可以了)
条款16
条款18 让接口容易被正确使用,不易被误用。
条款19 设计class犹如设计type
条款20 宁以pass by reference to const 替换 pass by value
条款21 必须返回对象时别妄想返回引用
条款22 将成员变量声明为private
条款10 令operator= 返回一个 reference to *this
这样可以实现链式赋值:
Widget& operator=(const Widget& w1) { //... return *this; }
条款11 在operator= 中处理“自我赋值”
防止用户不小心自我赋值或者不排除有这种需求,必须排除自我赋值可能带来的问题,下面演示一种可能会出现的问题。
class BitMap{//...}; class Widget { //... private: BitMap* pb; } Widget& Widget::operator(const Widget& rhs) { delete pb; pb = new BitMap(*rhs.pb); //如果是自我赋值的情况现在pb就是野指针 return *this; }
改良:
Widget& Widget::operator(const Widget& rhs) { if(this == &rhs) return *this; delete pb; pb = new BitMap(*rhs.pb); //如果是自我赋值的情况现在pb就是野指针 return *this; }
其他做法:
条款12 复制对象时不要忘了其每一个成分
1.Copying函数应该确保复制对象时不要忘了其每一个成分,派生类不要忘了基类。
2.不要尝试以某一个Copying函数去实现另一个Copying函数,可以把相同的逻辑放在一个单独的函数中,Copying函数再去调用这个函数。
条款13 以对象管理资源
为防止资源泄漏,请使用RAII对象,在构造函数中获得资源,析构函数中释放资源。
条款14 条款15 条款17(历史问题,直接用智能指针就可以了)
条款16
1. 如果你在new表达式中用了[] 那么delete也要加 [],反之,new中没有加[],delete也不要加。
条款18 让接口容易被正确使用,不易被误用。
条款19 设计class犹如设计type
1.新type的对象应该如何被创建和销毁?
2.对象的初始化和赋值有什么区别?
3.新type被值传递意味着什么?
4.什么是新type的合法值?
5.你的新type需要配合某个继承图系吗?
6.你的新type需要什么样的类型转换?
7.什么样的操作符和函数对新type是合理的?
8.什么样的标准函数(系统自带的函数)应该被驳回?
9.谁会用到新type成员,(注意权限)?
10.
11.你的新type有多么一般化(考虑设计为模板类)?
12.你真的需要一个新type吗?
条款20 宁以pass by reference to const 替换 pass by value
减少不必要的拷贝(看具体场景具体分析而使用)。
条款21 必须返回对象时别妄想返回引用
注意不要对(出了作用域会释放的变量)返回引用,更不要写出new 完这个变量再返回引用。1.自己new的对象自己释放不要指望调用这个函数的人帮你释放;
条款22 将成员变量声明为private
通过函数的方式去控制成员变量;
好处:
- 可以控制只读,只写,读写等,比较灵活,对其封装也可以做更多的事情。
- 对函数的修改,调整也不会被调用者感知。