• 类的拷贝管理


    拷贝控制:
    拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符,析构函数

    //拷贝构造函数//
    class Sales_data {
    public:
        Sales_data(const Sales_data &);
        Sales_data & operator = (const Sales_data &);
    private:
        string bookNo;
        int uints_sold = 0;
        double revenue = 0.0;
    };
    Sales_data::Sales_data(const Sales_data &orig) : bookNo(orig.bookNo), uints_sold(orig.uints_sold), revenue(orig.revenue) {}


    如果没有定义拷贝构造函数,编译器会定义一个。即使自己定义了拷贝构造函数,编译器也会合成一个。
    Sales_data::Sales_data(const Sales_data &orig) : bookNo(orig.bookNo), uints_sold(orig.uints_sold), revenue(orig.revenue) {}
    拷贝初始化:
    直接初始化:string dot(10,'.');
    拷贝初始化:string s2 = dot;
    //拷贝构造函数发生:将对象作为实参传给非引用的形参
    //返回一个非引用类型的对象
    //使用=进行拷贝

    1 Sales_data & Sales_data::operator = (const Sales_data &rhs) {
    2     return *this;
    3 }//赋值运算符
    4 extern  vector<vector<int>> Permutations(vector<int > &nums);


    三五法则
    //需要析构函数的类也需要拷贝和赋值操作

    class HasPtr {
    public:
        HasPtr(const string &s = string()) :ps(new std::string(s)), i(0) {};
        ~HasPtr() { delete ps; }
    private:
        string *ps;
        int i;
    };


    //使用默认的拷贝构造函数和拷贝赋值运算符,导致多个HasPtr对象指向相同内存

    HasPtr f(HasPtr hp) {
        HasPtr ret = hp;
        return ret;
    }

    //ret和hp的ps以及传入实参都指向统一内存,析构函数调用时会出现delete两次相同内存,出新错误

    需要拷贝操作的类也需要赋值操作

    class numbered {
    public:
        numbered(const numbered &num) = delete;//删除阻止拷贝
        numbered() = default;//显示
    private:
        int mysn;
    };//析构函数不能是删除的成员删除的成员
    struct PersonInfo {
        string name;
        vector<string> phones;
    };
     1 //行为像值的类
     2 class HasPtr {
     3 public:
     4     HasPtr(const string &s = string()) :ps(new std::string(s)), i(0) {};
     5     HasPtr(const HasPtr &p) :
     6         ps(new std::string(*p.ps)), i(p.i) {};
     7     
     8     ~HasPtr() { delete ps; }
     9 private:
    10     string *ps;
    11     int i;
    12 };
    13 HasPtr& HasPtr::operator = (const HasPtr &rhs) {
    14     auto newp = new string(*rhs.ps);
    15     delete ps;//释放旧内存
    16     ps = newp;
    17     i = rhs.i;
    18     /*delete ps;
    19     ps = new string(*(rhs.ps));
    20     i = rhs.i;*///自赋值会出现错误,比如rhs和本对象是通过一个对象
    21     return *this;
    22 }
    23 
    24 //行为像指针的类
    25 //最好的方法是使用shared_ptr来管理类中的资源,第二种是引用计数
    26 //除了初始化对象外,每个构造函数要创建一个引用计数
    27 //拷贝构造函数不分配新的计数器而是拷贝给顶对象的数据成员,包括计数器,拷贝构造函数递增共享的计数器
    28 //析构函数递减共享的计数器
    29 //拷贝赋值运算递增右侧运算对象的计数器,递减左侧对象的计数器
    30 
    31 
    32 
    33 //将计数器保存在动态内存中
    34 class HasPtr {
    35 public:
    36     //构造函数分配新的string和新的计数器,计数器值置1
    37     HasPtr(const string &s = string()) :ps(new std::string(s)), i(0),use(new std::size_t(1)) {};
    38     HasPtr(const HasPtr &p) :
    39         ps(p.ps), i(p.i), use(p.use) {
    40         ++*use;//递增计数
    41     };//ps保存拷贝对象的内存
    42 
    43     ~HasPtr() {  }
    44 private:
    45     string *ps;
    46     int i;
    47     std::size_t *use;
    48 };
    49 HasPtr::~HasPtr() {
    50     if (--*use == 0) {
    51         delete ps;
    52         delete use;
    53     }
    54 }
    55 HasPtr& HasPtr::operator = (const HasPtr &rhs) {
    56     ++*rhs.use;
    57     if (--*use == 0) {
    58         delete ps;
    59         delete use;
    60     }
    61     ps = rhs.ps;
    62     i = rhs.i;
    63     use = rhs.use;        
    64     return *this;
    65 }
    66 class  HasPtr {
    67 
    68     friend void swap(HasPtr&, HasPtr&);
    69         HasPtr(const string &s = string()) :ps(new std::string(s)), i(0) {};
    70         ~HasPtr() { delete ps; }
    71     private:
    72         string *ps;
    73         int i;
    74 
    75 };
    76 inline void swap(HasPtr &lhs, HasPtr &rhs) {
    77     using std::swap;
    78     swap(lhs.ps, rhs.ps);
    79     swap(lhs.i, rhs.i);
    80 }
  • 相关阅读:
    面试中你能做到随机应变吗? 沧海
    QQ只是一场意外 沧海
    面 试 中 要 慎 言 沧海
    你会应对这些面试题吗? 沧海
    面 试 小 技 巧 沧海
    面试抓住最初三分钟至关重要 沧海
    面试的十二种高级错误 沧海
    几种有难度的面试 沧海
    面试技巧: 轻松过关10种方法 沧海
    面 试 细 节 一 点 通 沧海
  • 原文地址:https://www.cnblogs.com/bingzzzZZZ/p/8426066.html
Copyright © 2020-2023  润新知