//条款18:让接口容易被正确使用,不易被误用 // 1.若是客户企图使用某个接口而却没有得到他所预期的行为,那么这个代码就不应经过编译。 // 2.促进正确使用的方法包括接口的一致性,以及与内置类型的行为兼容。 // 3.阻止误用的方法包括创建新类型、限制类型上的操做,束缚对象值,以及消除客户的资源管理责任。 // 4.shared_ptr支持自定义删除器,能够方便的用于管理各类资源。 //条款20:pass by reference to const 替换 pass by value // 1.C++的底层操做会将传引用操做以指针的形式来实现。 // 2.传递const的引用能够避免父对象接收子对象时候面临的子对象被切割的问题。 // 3.传递const的引用能够有效避免无谓的拷贝和销毁操做,在性能上产生优点 // 4.对于内置类型以及STL的迭代器以及STL中的函数对象,对它们而言传递值比传递引用更加适当。对于此条规则,经vs2010测试发现,传值与传引用几乎没什么差异,因此统一使用传引用代替传值是能够的。 //条款22:将成员变量声明为private // 1.将成员变量声明为private的,这能够赋予客户访问数据的一致性、可细微划分访问控制、允诺约束条件得到保证,并让类的设计者以充分的实现弹性。 // 2.切记protected并不比public更具封装性。若子类以public方式继承,则能够经过using轻松改变父类中protected成员的访问权限。 //条款23:以非成员函数、非友元函数替换成员函数 // 1.越少的代码能够访问到类的私有成员数据,那么类的私有成员数据的封装性就越好。 // 以下代码:ClearCTestData()函数被声明为类的非成员函数,使得能访问类的私有成员的函数减小,这就提升了类的数据的封装性。如此当改变了类的数据成员的时候,须要被改变的代码量就会减小。 class CTest { public: CTest() : value0(0), value1(0){} public: void ClearValue0(){value0 = 0;} void ClearValue1(){value1 = 0;} private: int value0; int value1; }; void ClearCTestData(CTest &Test) { Test.ClearValue0(); Test.ClearValue1(); } // 2.上述的ClearCTestData()系列函数,一般是做为类的辅助工具提供的,将其声明为类的非成员函数,能够下降编译的依存性。 //条款24:若全部参数均可能须要类型转换,那么最好将其声明为类的非成员函数 //1.以下代码: class CTest { public: CTest (int nTemValue) : value(nTemValue){} public: const CTest operator * (const CTest& tem) const {return CTest(value * tem.value);} //此处之因此不是返回一个引用而是按值返回一个对象,是为了防止引用对象不存在的状况。 int GetValue() const {return value;} //为了使得常量对象也能调用此函数,必须将其声明为常量成员函数。 private: int value; }; const CTest FunTest(const CTest &tem0, const CTest &tem1) { return CTest(tem0.GetValue() * tem1.GetValue()); } CTest Test0(1); CTest Test1 = Test0 * 2; //容许经过编译 //CTest Test2 = 2 * Test0; //不容许经过编译 //之因此CTest Test1 = Test0 * 2;能经过编译,是由于发生了隐式类型转换,将2转换为CTest类型 //之因此CTest Test2 = 2 * Test0;不能经过编译,是由于只有参数位于参数列表中,这个参数才能发生隐式类型转换。 CTest Test2 = FunTest(2, 2); //容许经过编译,须要隐式转换的参数都位于形参列表中 //条款25:考虑为类写出一个不抛出异常的swap函数 // 1.swap是一个有趣的函数,本来是STL的一部分,然后来成为异常安全性变成的脊柱,以及用来处理自我赋值的可能性。 // 2.当std::swap对自定义的类型效率不高的时候(好比在这个类型中使用了指针指向了一个内存,如此swap应该交换指针而非交换指针所指对象),提供一个swap成员函数,并肯定这个函数不抛出异常 // 3.若是提供一个成员函数swap,那么也该提供一个非成员函数版本的swap来调用成员函数版本的swap。 // 4.不要试图往std命名空间中添加新的成员,这种行为是未定义的。