zoukankan      html  css  js  c++  java
  • 【c++】拷贝控制具体分析

    我们可以定义拷贝操作,使类的行为看起来像一个值或者像一个指针,这取决于如何拷贝指针成员。

    当我们拷贝一个像值的对象时,副本和原对象是完全独立的,改变副本不会对原对象有任何影响,反之亦然。标准库容器和string类的行为像一个值。

    当我们拷贝一个行为像指针的类的对象时,副本和原对象使用相同的底层数据,改变副本也会改变原对象,反之亦然。

    浅拷贝,指的是在对象复制时,只是对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝。这样一来可能出现多个指针指向同一块内存的情况

    在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间

    一、行为像值的类(不同的类对象的指针数据成员指向独立的内存空间)

    class HasPtr
    {
    public:
        HasPtr(const HasPtr&) :ps(new string(*p.ps), i(p.i)){}
        HasPtr& operator=(const HasPtr &);
        ~HasPtr(){ delete ps; }
    private:
        string *ps;
        int i;
    };
    /*
    通过先拷贝右侧运算对象,我们可以处理自赋值情况,并能保证异常发生时代码安全。  
    注意:1、返回值 2、自赋值 3、new异常。 解决方案:返回引用,先判断是否自赋值,若是则返回,在释放旧内存前先分配好内存
    */ HasPtr& HasPtr::operator=(const HasPtr &rhs) { auto newp = new string(*rhs.ps);//拷贝底层string delete ps;//释放旧内存 ps = newp; i = rhs.i;
    //处理连锁赋值
    return *this; } HasPtr& HasPtr::operator=(const HasPtr &rhs) { delete ps;//释放旧内存 //如果rhs和*this是同一个对象,我们就将从已释放的内存中拷贝数据 ps = new string(*rhs.ps); i = rhs.i; return *this; }

    二、定义行为像指针的类(多个类对象的指针指向同一个地址,但不能出现错误)

    因为可能会有多个类的指针指向同一个地址,所以使用引用计数,引用计数是个指针,如果是个值得话,考虑下面情况(值得话每个对象都保存一个副本,互相独立)。

    HasPtr p1("ljy");

    HasPtr p2(p1);

    HasPtr p3(p1);//p1,p2,p3指向相同的string,若引用计数是值的话,无法更新View Code

    class HasPtr
    {
    private:
        string *ps;
        int i;
        int *use;
    public:
        HasPtr(const HasPtr &p) :ps(p.ps), i(p.i), use(p.use){ ++*use; }
        HasPtr& operator=(const HasPtr&);
        ~HasPtr();
    };
    
    HasPtr::~HasPtr()
    {
        if (--*use == 0)
        {
            delete ps;
            delete use;
        }
    }
    
    HasPtr& HasPtr::operator=(const HasPtr &rhs)
    {
       //先++rhs.use,可以处理自赋值的情况
        ++*rhs.use;
        if (--*use == 0)
        {
            delete ps;
            delete use;
        }
        ps = rhs.ps;
        i = rhs.i;
        use = rhs.use;
        return *this;
    }
  • 相关阅读:
    DOM节点删除之empty()和remove()的有参用法和无参用法
    DOM外部插入insertAfter()与insertBefore()
    DOM内部插入prepend()与prependTo()
    DOM外部插入after()与before()
    DOM内部插入append()与appendTo()
    jQuery节点创建与属性的处理 创建节点
    jQuery的属性与样式之元素的数据存储
    jQuery的属性与样式之样式操作.css()
    jQuery的属性与样式之切换样式.toggleClass()
    jQuery的属性与样式之增加样式.addClass()
  • 原文地址:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/3837783.html
Copyright © 2011-2022 走看看