Designs and Declarations #
18.Make interfaces easy to use correctly and hard to use incorrectly #
-
好的接口容易被正确使用 ,不容易被误用
-
阻止误用的办法包括建立新类型、限制类型上的操作,束缚对象值,以及消除客户的资源管理责任
19.Treat class design as type design #
-
Class的设计就是type的设计
-
标准string和STL窗口都不被设计作为base classed使用,因为它们的析构函数都不带virtual
20.Prefer pass-by-reference-to-const to pass-by-value #
-
对于内置类型,以及STL的迭代器和函数对象,使用pass-by-value更合适
-
C++编译器底层中的references往往是以指针方式实现的,意味着真正传递的是指针
21.Don’t try to return a reference when you must return an object #
当必须返回新对象时,就让那个函数返回新对象,如下
inline const Rational operator* (const Ratinal& lhs,const Rational& rhs)
{
return Rational(lhs.n * rhs.n,lhs.d * rhs.h);//编译器会优化掉构造和析构的开销
}
不要返回pointer 或reference指向一个local stack 对象,也不要返回reference指向一个heap-allocated对象,也不要返回pointer或reference指向一个local static 对象,因为有可能 同时需要多个这样的对象
//不推荐
inline const Rational operator* (const Ratinal& lhs,const Rational& rhs)
{
static Rational result;
result = ...;
return result;
}
22.Declare data members private #
切记将成员变量声明为private,利用封装性
23.Prefer non-member non-friend functions to member functions #
宁可拿non-member non-friend函数替换member函数
class WebBrowser{
public:
void clearCache();
void clearHistory();
void remove Cookies();
};
class WebBrowser{
public:
void clearEverything()
{
clearCache();
clearHistory();
remove Cookies();
}
private:
void clearCache();
void clearHistory();
void remove Cookies();
};
//更推荐的做法
void clearBrovser(WebBrowser& wb)
{
wb.clearCache();
wb.clearHistory();
wb.remove Cookies();
}
24.Declare non-membe functions when type conversions should apply to all parameters #
如果需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member
class Rational{
public:
Rational(int numerator = 0,int denominator = 1);//允许隐式类型转换
int numerator() const;
int denominator() const;
public:
const Rational operation*(const Rational& rhs) const;
};
Rational oneEighth(1,8);
Rational oneHalf(1,2);
Rational result = oneHalf * oneEighth;
result = result * oneEighth;
result = oneHalf * 2;//OK 隐式类型转换
result = 2 * oneHalf;//==>2.operator*(oneHalf) 错误
class Rational{
...
};
const Rational operator*(const Rational& lhs,const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
}
Rational oneFourth(1,4);
Rational result;
result = oneFourth * 2;//OK 隐式类型转换
result = 2 * oneFourth;//OK 隐式类型转换
25.Consider support for a non-throwing swap #
std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常
namespace WidgetStuff{
template<typename T>
class Widget{
...
void swap(Widget& other)
{
using std::swap;
swap(pImpl,other.pImpl);
}
};
...
template<typename T>
void swap(Widget<T>& a,Widget<T>& b)
{
a.swap(b);
}
}
template<typename T>
void doSomething(T& obj1,T& obj2)
{
using std::swap();
swap(obj1,obj2);//为T类型对象调用最佳swap版本
}