C++之拷贝构造、赋值构造必须为引用?

转载自C++ 为什么拷贝构造函数参数必须为引用?赋值构造函数参数也必须为引用吗?


之前写拷贝构造函数的时候,以为参数为引用,不为值传递,仅仅是为了减少一次内存拷贝。然而今天看到一篇文章发现自己对拷贝构造的参数理解有误。 参数为引用,不为值传递是为了防止拷贝构造函数的无限递归,最终导致栈溢出。

class test
{
public:
    test()
    {
        cout << "constructor with argument\n"; 
    }
    ~test()
    {
    }
    test(test& t)
    {
     cout << "copy constructor\n"; 
    }
    test&operator=(const test&e)
    {
        cout << "assignment operator\n";  
        return *this;
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    test ort;
    test a(ort);
    test b = ort ;
     a = b;
    return 0;
}

输出结果:
这里写图片描述

如果复制构造函数是这样的 :

test(test t);

我们的执行过程是:

//test ort;
//test a(ort); --> test.a(test t=ort)==test.a(test t(ort))
//              -->test.a(test t(test t = ort))
//                 ==test.a(test t(test t(ort)))
//              -->test.a(test t(test t(test t=ort)))
//               ...
//    就这样会一直无限递归下去。

到这里,我们也就明白了,为什么拷贝构造函数的参数一定要为引用,不能为值传递的原因了。

接下来,我们再测试一下赋值构造函数的参数,如果我们把它的参数也改为值传递,做一个测试。

class test
{
public:
    test()
    {
        cout << "constructor with argument\n"; 
    }
    ~test()
    {
    }
    test(test& t)
    {
     cout << "copy constructor\n"; 
    }
    test&operator=(test e)
    {
        cout << "assignment operator\n";  
        return *this;
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    test ort;
    test a(ort);
    test b = ort ;
     a = b;
    return 0;
}

输出结果为:

这里写图片描述

赋值构造函数如果为值传递,仅仅是多了一次拷贝,并不会无限递归。

总结

拷贝构造函数的参数必须为引用。赋值构造函数参数既可以为引用,也可以为值传递,值传递会多一次拷贝。因此建议赋值构造函数建议也写为引用类型。(CKK看 刚才我的理解还是有偏差:左右值不是关键,减少拷贝次数提高赋值效率是重点)

扫描二维码关注公众号,回复: 3020834 查看本文章

猜你喜欢

转载自blog.csdn.net/ReturningProdigal/article/details/78843443