举个必须要用重载运算符和重载运算符时必须要使用引用的例子

class Myclass {
private:
    char* str;
public:
    Myclass( char* str1 = "default string" )
    {
        str = new char[strlen( str1 ) + 1];
        strcpy( str, str1 );
        cout << "constructor called" << endl;
    }
    ~Myclass()
    {
        cout << "destrustor called" << endl;
    }


    void showChar()
    {
        cout << str << endl;
    }


    Myclass &operator = (const Myclass &ele) {
        delete[] str;
        str = new char[strlen( ele.str ) + 1];
        strcpy( str, ele.str );
        return(*this);
    }
};

int main()
{
    Myclass class1( "string1" );


    Myclass class2;
    class2 = class1;
    class1.showChar();
    class2.showChar();
    return(0);
}

这里我们重载了赋值运算符,将class1的str赋给了class2.str;

若我们不重载赋值运算符,用原来自带的‘=’,则会调用复制构造函数,将class1的str的值复制给class2的str,这是两个str指向统一内存。在程序完成时,调用析构函数,先调用class2的析构函数,把str所指向的内存给清除,完成后再调用class1的析构函数,由于在class2时已经把str所指向的内存给清除了,这时会出现内存泄漏。

为什么这里的重载赋值运算符一定要用引用?

若参数不用引用,则有Myclass &operator=(const Myclass ele) {

这时实参传值给形参会创建一个临时变量,调用复制构造函数将实参复制给形参,实参的str与形参的str指向同一块内存。所以,当赋值函数完成时,会清除函数的所占的内存,形参就会被清除,形参的str指向的内存也就会被清除。再调用class1.showchar()会发现内存泄漏。

输出结果如下:

constructor called

constructor called

䁷䁷䁷䁷䁷

string1

destrustor called

destrustor called

若重载运算符函数的返回类型不用引用,则有则有Myclass operator=(const Myclass &ele) {

这是返回对象时会创建一个临时对象,再调用复制构造函数,将返回的对象复制给临时对象,函数结束后,返回的对象被清除,返回对象的str所指向的内存也被清除,由于返回对象和临时对象的 str指向同一块内存,所以calss2=class1的str指向一块随机内存,在调用class2.showchar()时会随机输出。

输出结果如下:

constructor called

constructor called

string1

䁷䁷䁷䁷䁷

destrustor called

destrustor called

此外:

(class2=class1)=class3是不允许的,编译器不允许临时对象调用成员函数。

因此这种情况必须要用引用来传递参数和返回参数,使用引用返回的参数可以作为左值。

原文:https://blog.csdn.net/youyou362/article/details/75023797