菜鸟笔记
提升您的技术认知

赋值运算符重载-ag真人游戏

c语言中允许把一个结构体赋值给另外一个相同类型的结构体,c 允许把一个对象赋值给另一个同类的对象。这是通过自动为类重载赋值运算符实现的。这种赋值运算符重载函数原型如下。

class_name & class_name::operator=(const class_name &);

它接受一个指向类对象的常引用,并返回一个指向类对象的引用。c 自动提供的这个函数实现了浅拷贝。接着上篇博文的例子来验证一下。

例1

#include
#include
#include
using namespace std;
class man {
    char* name;
    int age;
    public:
        man(char* name, int age);
        man();
        man(const man & m);
        ~man();
        void show();
};
man::man(char* name, int age)
{
    cout<<"call self-def constructor"<name = new char[strlen(name)   1];
    strcpy(this->name, name);
    this->age = age;
}
man::man()
{
    cout<<"call default constructor"<name = new char[8];
    strcpy(this->name, "unknown");
    age = -1;
}
man::~man()
{
    cout<<"call destructor"<age = m.age;
    this->name = new char[strlen(m.name)   1];
    strcpy(this->name, m.name);
}
int main()
{
    man a = man((char*)"zhengkang", 26);
    man b;
    b = a;
    a.show();
    b.show();
    return 0;
}

这个例程的运行结果如下

从运行结果可以看出,a的name指针和b的name指针指向同一片内存区域。执行b = a;跟默认的拷贝构造函数一样,实现的是浅拷贝,那么浅拷贝存在的问题在这里同样存在。释放a的name指向的内存会导致b的name指针指向的内存也被释放掉,这就是需要重载赋值运算符的原因。

进行赋值运算符重载实现深拷贝与拷贝构造函数类似,但是也有一些区别。

  1. 由于目标对象可能引用了以前分配的数据,所以函数应该使用delete[]来释放内存。
  2. 函数应该避免将对象赋值给自己,否则的话,给对象重新赋值前,释放内存操作可能删除对象的内容。
  3. 函数需要返回一个指向调用对象的引用。通过返回这样一个引用,可以实现链式操作(即连续赋值),假如a,b,c都是man对象,那么可以这样写a=b=c;等价于a.operator=(b.operator=(c));

下面,我们重载赋值运算符函数。

例2

man& man::operator=(const man& m)
{
    cout<<"call = overload func"<

重新运行程序,结果如下:

两个对象的name指针指向了不同的内存区域,互不影响。

下面两条语句可能会让人疑惑,需要区分清楚。

man b;
b = a;		//调用复制运算符重载函数进行对象赋值
man c = a;   //调用拷贝构造函数

例3

int main()
{
    man a = man((char*)"zhengkang", 26); //调用带参数的构造函数
    man b = a; //调用拷贝构造函数
    man c;    //调用默认构造函数
    c = a;    //调用复制运算符重载函数进行对象赋值
    return 0;
}

运行结果:

网站地图