zoukankan      html  css  js  c++  java
  • 三五法则

    1.概念

    1)“三”是指拷贝构造函数、拷贝赋值运算符、析构函数这三者之间关系,“五”是在前面三个的基础之上再加上移动构造函数、移动赋值运算符这两个

    2.法则一:需要自定义析构函数的类也需要自定义拷贝和赋值操作

    1)当类含有指针成员,构造函数new了一块动态内存并让这个指针成员指向它,这个类析构时就需要执行delete去释放指针指向的内存,但是合成析构函数不会delete这个指针,所以这种类需要自定义析构函数

    2)同时,这种类在发生拷贝或者赋值时,如果执行合成拷贝构造函数和合成拷贝赋值运算符,只会进行简单的浅拷贝,会使得多个类对象的指针成员指向同一块内存;这样的话,当某个类对象结束了它的生命周期,会执行它自定义的析构函数,delete它的指针成员,于是这块内存便被释放了,那么此时其他的类对象的指针成员将成为空悬指针,或者多个类对象同时被销毁时,这块内存会被delete多次,这都是会发生错误的

    3)浅拷贝:在进行类对象拷贝时,如果类对象含有指针成员,浅拷贝是仅仅拷贝了一个指针,让这个指针也指向原来已经存在的内存

    4)深拷贝:深拷贝是生成一个指针,并新开辟了一块内存,把原来那块内存上的内容拷贝过去,并让新生成的指针指向这块新内存

    5)默认拷贝构造函数,进行的是浅拷贝,会发生上述所说的错误,所以要自定义拷贝构造函数和拷贝赋值运算符,进行深拷贝

    class HasPtr {
    public:
        HasPtr(const string& s = string()) : i(0) {
            ps = new string(s);
        }
        //自定义拷贝构造函数
        HasPtr(const HasPtr& hp) : i(hp.i) {
            ps = new string(*hp.ps);
        }
        //自定义拷贝赋值运算符
        HasPtr& operator = (const HasPtr& rhs_hp) {
            if (this != &rhs_hp) 
    {
    string *temp_ps = new string(*rhs_hp.ps);//new在delete前,为了保证安全性,如果new不出来,那么异常就在这发生了,下面那行delete就不不会发生了 delete ps; ps = temp_ps; i = rhs_hp.i; }//temp_ps离开了它的作用域,指针本身被销毁,但是它指向的动态内存不会被销毁,因为没有执行delete return *this; } //自定义折构函数 ~HasPtr() { delete ps; } private: string *ps; int i; };

    6)基类的析构函数可以不遵循此法则:一个基类总是需要虚折构函数来防止内存泄露

    • 首先要明确的是,每个析构函数只会清理自己所在层级创造的成员
    • 当delete一个指向派生类对象的基类指针时,如果基类的析构函数没有定义成虚函数,则编译器实现静态绑定,在delete这个基类的指针时,只会执行基类的析构函数,释放基类成员,派生类成员得不到释放,此时会导致释放内存不完全,导致内存泄露

    3.法则二:需要自定义拷贝操作的类也需要自定义赋值操作,反之亦然

    1)一个类有一个数据成员代表编号,当需要这个类的每一个类对象都有一个唯一的编号,此时如果仅仅使用合成拷贝构造函数的话,发生拷贝时,拷贝出来的对象的编号肯定就一样了,这个时候就需要自定义拷贝构造函数

    2)这种情况下需要自定义拷贝构造函数,那肯定也要自定义拷贝赋值运算符,反过来也是一样的道理

    4.法则三:一般来说,如果一个类定义了任何一个拷贝控制成员,它就应该定义所有五个拷贝控制成员

    1)如前所述的类必须定义析构函数、拷贝构造函数、拷贝赋值运算符才能正常工作,这些类通常拥有一个资源,拷贝成员会拷贝资源,一般来说,拷贝资源会导致一些额外开销,在某些情况下,移动构造函数和移动赋值运算符能不开辟新内存完成对对象的移动,减少开销,所以定义它俩有必要

  • 相关阅读:
    Atitit.Java exe bat  作为windows系统服务程序运行
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.office word  excel  ppt pdf 的web在线预览方案与html转换方案 attilax 总结
  • 原文地址:https://www.cnblogs.com/Joezzz/p/9683787.html
Copyright © 2011-2022 走看看