仿爱范儿网wordpress主题,百度seo优化策略,黑龙江省和城乡建设厅网站,网站初期缺点条款14#xff1a;在资源管理类中小心copy行为当我们深入理解“资源取得时机是初始化时机#xff08;RAII#xff09;”概念#xff0c;并以此作为“资源管理类”的核心时#xff0c;我们可能会遇到将RAII对象复制的情况#xff0c;一般有两种情况处理这个现象#xff1…条款14在资源管理类中小心copy行为当我们深入理解“资源取得时机是初始化时机RAII”概念并以此作为“资源管理类”的核心时我们可能会遇到将RAII对象复制的情况一般有两种情况处理这个现象1如果我们的RAII对象是唯一的那么复制就不合理因此我们应该禁止copy构造的行为正确的处理方式将copy函数定义为private(base class),并用derived class private继承这个函数来阻止copy行为; 2)使用引用计数法即智能指针的形式来实现对所有拷贝资源的追踪但是智能指针的缺省行为是当引用次数为0时删除其所指向的对象。如果我们要实现的功能不是释放资源这时候就应该自定义智能指针的deleter(一个函数或者函数对象当引用次数为0时调用这个函数实现相应功能如
class lock{
public:explicit lock(mutex *pm) : mutexptr(pm,unlock) { } //用mutex初始化shared_ptr,并以unlock函数为删除器
private:std::tr1::shared_ptrmutexmutexptr;
};
另外上述例子中不需要声明析构函数因为class 析构函数会自动调用其non-static成员变量的析构函数3复制底部资源采用深度拷贝的方法4采用转移底部资源拥有权的方法也就是所谓的auto_ptr指针
条款15在资源管理类中提供对原始资源的访问当你需要访问一个RAII class对象的内部原始资源时有两种方法可以达成目标:1)在类的内部提供一个get成员函数用来执行显示转换也就是返回类内部指针的原始复件2允许隐式转换到底部原始指针在智能指针中重载了指针取值操作符operator-和operator*来实现隐式转换对于一般的来说可以在类中提供一个隐式转换函数如
class font{
public: //显示转换函数explicit font(fonthandle fh) : f(fh){ } fonthandle get() const { return f; }~font() { releasefont(f); } //隐式转换函数
private: operator fonthandle() const {return f;}//没太明白怎么隐式转换的fonthandle f; //operator起到什么作用
}
//显示转换 //隐式转换
void changefontsize(fonthandle f,int newsize); void changefontsize(fonthandle f,int newsize);
font f(getfont()); font f(getfont());
changefontsize ( f.get(), newfontsize); changefontsize ( f, newfontsize);
//但隐式转换会出一个问题
font f1(getfont());
fonthandle f2f1; //原意是拷贝结果是f1先转化为底部的fonthandle然后拷贝一旦此时f1被销毁f2就处于指向资源被释放的状态dangle
条款16成对使用new和delete时采取相同的方式如果你在new的表达式中使用[ ]则必须在相应的delete表达式中也使用[ ],如果没有使用[ ]那么也一定不要在delete中使用[ ];
条款17以单独语句将newed对象置入智能指针中对于以下代码分析int priority( );void processwidget(std :: tr1 :: shared_ptrwidegetpw,int priority);//调用时 processwidget(new widget, priority( ));//编译错误shared_ptr构造函数是explicit类型不允许隐式转换//processwidget(std :: tr1 :: shared_ptrwideget(new widget),priority( ) );这个函数在调用processwidget之前编译器必须创建代码完成以下三件事情1调用priority;2)执行new widget;3)调用 std::tr1::shared_ptr构造函数但是1和2的执行顺序和编译器有关如果先执行2后执行1且在执行1的时候发生异常那么new widget返回的指针就会失效那么内存泄露就产生了解决上述问题的方法使用分离语句把创建对象和给智能指针赋初值的语句分离出来,原因是编译器对于“跨越语句的各项操作”没有重新排列的自由只有在语句内才拥有那个自由度代码如下std::tr1::shared_ptrwidgetpw(new widget);processwidget(pw,priority( ));