您的当前位置:首页正文

赋值运算符“=”的重载 (浅拷贝与深拷贝)

来源:九壹网

赋值运算符是双目运算符,如果没有用户自定义的赋值运算符函数,那么系统将自动地为其生成一个默认的赋值运算符函数实现对象的赋值

Complex c1(10,20),c2;

就调用默认的赋值运算符函数,将对象c1的数据成员逐一拷贝到对象c2中,即

c2.real=20;

c2.imag=10;

虽然默认的赋值运算符函数能够实现很多拷贝,但是有很多时候它是不行的,这时需要自己对赋值运算符进行重载

浅拷贝产生的指针悬挂问题     

在浅拷贝中,是简单的赋值给另一个成员,如果里面有指针,则导致两个对象的指针指向相同的内存。由于指针在两个对象例指向相同的变量,当一个对象改变的时候则另一个对象会跟着改变。另一方面,我们不知道究竟由谁在负责析构指针开辟的堆内存,这样就会出现一下错误。调析构函数则析构两次,破坏内存;不调用析构则没有析构,造成内存泄露。

#include<iostream>
#include<string.h>
using namespace std;
class STRING
{
public:
    STRING(char *s)
    {
        cout<<"constructor  called"<<endl;
        ptr=new char[strlen(s)+1];
        strcpy(ptr,s);
    }
    ~STRING()
    {
        cout<<"Destructing called---"<<ptr<<endl;
        delete []ptr;
    }
private:
    char *ptr;
};
int main()
{
    STRING p1("book");
    STRING p2("jeep");
    p2=p1;
    return 0;

}





当类里有成员是指针时,并且动态分配了内存,我们应该重载赋值函数,实现一个深拷贝(physical copy)。

1.首先我们要检查是不是自身赋值,如果是应该立即返回(不要做其他事情);

2.如果不是自身赋值,我们要释放指针所指向的堆内存;

3.把右边对象的成员拷贝并值赋给左边对象的成员值;

4.最后,我们要返回返回本类对象的一个常引用,避免链式赋值(返回const对象引用,不让x=y=z)。



#include<iostream>
#include<cstring>
using namespace std;
class STRING
{
public:
    STRING(char *pt)
    {
        cout<<"constructing called   "<<endl;
        ptr=new char[strlen(pt)+1];
        strcpy(ptr,pt);
    }
    ~STRING()
    {
        cout<<"Destructing called   "<<ptr<<endl;
        delete ptr;
    }
    STRING& operator=(const STRING &);
private:
    char *ptr;
};
STRING& STRING::operator=(const STRING &p)   // 重载赋值运算符必须是类的成员,重载赋值运算符应返回一个类的对象的引用。
{
    if(this==&p) return *this;   //
    delete []ptr;    //如果不是对自身赋值的话,先将p2所指向的旧区域释放掉
    ptr=new char[strlen(p.ptr)+1];  //重新给p2分配一个新区域
    strcpy(ptr,p.ptr);      //将后者地址中的值拷贝给前者
    return *this;   //返回自引用到下面语句@   使函数能够继续向下执行
}
int main()
{
    STRING p1("book");
    STRING p2("jeep");
    p2=p1;      //@     p2=p1相当于p2.operator=(p1);
    return 0;

}




#include<iostream>
#include<cstring>
using namespace std;
class STRING
{
public:
    STRING(char *pt)
    {
        cout<<"constructing called   "<<endl;
        ptr=new char[strlen(pt)+1];
        strcpy(ptr,pt);
    }
    ~STRING()
    {
        cout<<"Destructing called   "<<ptr<<endl;
        delete ptr;
    }
    void operator=(const STRING &);
private:
    char *ptr;
};
void STRING::operator=(const STRING &p)   //函数返回为void
{
    if(this==&p) return ;
    delete ptr;
    ptr=new char[strlen(p.ptr)+1];
    strcpy(ptr,p.ptr);
//    return *this;
}
int main()
{
    STRING p1("book");
    STRING p2("jeep");
    p2=p1;          //@     p2=p1相当于p2.operator=(p1);   上面函数调用完成返回到此处  开始继续执行下面的c语句
    return 0;
}

结果都是

因篇幅问题不能全部显示,请点此查看更多更全内容

Top