C++(一)拷贝构造函数栈溢出的原因

来源:互联网 发布:你不知道的事 知乎 编辑:程序博客网 时间:2024/06/02 21:37

一、            什么是拷贝构造函数

就是构造函数的一种,用于实现同一类对象的构建和初始化。

拷贝构造函数是由普通构造函数赋值操作符共同实现的。

一般用于:

(1)   函数形参,值传递

(2)   函数返回值,值传递

(3)   一个对象给另一个对象初始化

如:Test a3=Test(a1);

因为值传递是传递对象的副本,所以会编译器会自动调用拷贝构造函数。

用一个已存在的对象对一个新的对象初始化,不会生成临时对象,而是新对象直接调用已存在对象的拷贝构造函数。

 

二、            如何重载赋值操作符

    Test&operator=(const Test &a)    {        this->data=a.data;        return *this;    }


三、            上述两者的纠结关系

 

先来看看如下的程序,实现了重载赋值操作符和拷贝构造函数:

#include <iostream>using namespace std; class Test{private :int data;public :   Test(){}   Test(int n):data(n){}   Test(const Test &old)    {       *this=old;      cout<<"拷贝构造函数!"<<endl;    }   Test &operator=(const Test &a)    {       this->data=a.data;       cout<<"赋值运算符重载啦"<<endl;       return *this;    }}; int main(){   Test a1(5);   Test a2;   a2=a1;   Test a3=Test(a1);   return 0;}


 

 

这就是被调用的重载赋值操作符函数:


其中:

如果红框中不加 & 引用标识符,那么函数返回值属于值传递,编译器调用拷贝构造函数生成一个对象副本。


如果红框中不加 & 引用标识符,那么函数参数值属于值传递,编译器调用拷贝构造函数生成一个对象副本。

这就是被调用的拷贝构造函数:


  调用了赋值操作符函数。

所以如果赋值操作符函数不是const & Test 引用类型,而是值传递,就会有:

    赋值运算符的参数值传递调用拷贝构造函数

拷贝构造函数中的“=”调用赋值运算符函数

赋值运算符的参数值传递调用拷贝构造函数

拷贝构造函数中的“=”调用赋值运算符函数

重复调用直至栈溢出。

 

 

总结:

(1)      拷贝构造函数的返回值和传入的参数一定要是引用类型(否则栈溢出),而且一般都是不希望参数在函数中被改变,所以是const 常引用。

(2)      拷贝构造函数用于,生成对象副本(值传递就会生成对象副本)和给新对象初始化时(新对象调用旧对象的拷贝构造函数)。

 

 

原创粉丝点击