Effective C++读书笔记(6)

来源:互联网 发布:关于网络诈骗的新闻 编辑:程序博客网 时间:2024/06/13 13:05
(1)swap相关
①设计自己swap的方法
设计swap的特化版本(用于不需要完全复制对象的那种,如impl方法
在成员函数中声明一个swap函数,用于跟同类型进行交换(因为外部函数无法访问为private的指针对象
例子:
class Widget
{
    public:
            void swap(Widget& other)    //注意这里不可能用const,因为other进入以后是要被改变的
            {
                    using std::swap;
                    swap(pImpl, other.pImpl);
            }
            .....       
};

namespace std
{
        template<>
        void swap<Widget>(Widget& a, Widget& b)
        {
                a.swap(b);
        }
}

②Widget和WidgetImpl都是模板类的情况下
应该在自己的明明空间内声明一个swap函数,在查找时编译器会先查找这里
namespace WidgetStuff
{
...
template<typename T> 
class Widget {...};                      //同前,内含swap函数
...
template<typename T>
void swap (Widget<T> &a, Widget<T> &b)
{
a.swap(b);
}
...
}

③优先调用特异化版本,没有再调用std::swap
template<typename T>
void doSomething(T& obj1, T& obj2)
{
...
using std::swap;    // 令std::swap在本函数内可用
...
swap(obj1, obj2);
...
}

④为“用户定义类型”进行std template全特化是好的,但是千万不要尝试在std内部加入某些对std而言全新的东西


(2)尽可能延后变量声明的时间,这样可以增加程序清晰度,增强效率,减少意外
(3)除非知道“赋值成本”比“构造+析构成本”低,否则应该将变量定义于循环内部
(4)关于转型
①注意:在子类中
            static_cast<Window>(*this).reSize()
            与
            Window::reSize()
            的意义不一样!前者是转换成一个只包含Window相关变量的副本。此时如果reSize中对成员变量做了操作,那么仅仅是改动的副本中的相关变量。这会带来错误
           ②不要连续使用dynamic_cast(上转下)这会非常慢
           ③如果可以,尽量避免转型
           ④用C++风格的转型代替默认风格的转型
(5)避免返回handle(包括指针,引用,迭代器)指向对象内部。否则会破坏private成员的封装性,const函数的const性质
(6)限制inline的使用
        ①inline对于函数升级没有响应
        ②对构造函数和析构函数inline可能会导致更多的成本(例如包含N多变量,变量的构造和析构会被编译器写入类的构造和析构中)
(7)将文件的编译依存关系降到最低。
        ①使用Imple方法(为定义式和声明式使用不同的头文件)
            1.指针和引用是不需要知道函数定义式的,所以这个时候只要声明class XXX就好了,一般用于定义接口中
            2.XXX xxx就需要定义式了,必须#include入XXX的头文件
        ②使用纯虚类
            
0 0