zoukankan      html  css  js  c++  java
  • 类的拷贝管理

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

    //拷贝构造函数//
    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 }
  • 相关阅读:
    XMLHttpRequest 对象 的属性与方法
    永远的福气 陈慧琳
    win32.Jadtre.B不用删除文件解决办法(网页嵌入一段恶意js )
    整理一些PHP函数,这些函数用的不是非常多,但是又非常重要,如果适当的用起来,有可以提升性能
    循环file_get_contents()部分内容不能获取的问题
    php下载图片到用户客户端
    php中break,continue,exit的使用与区别
    解决android setText不能int的问题
    用htaccess限制ip访问的方法
    查看表结构的命令show columns from 表名
  • 原文地址:https://www.cnblogs.com/bingzzzZZZ/p/8426066.html
Copyright © 2011-2022 走看看