转载自:http://blog.sina.com.cn/s/blog_6ab0b9a801019b3h.html
三种情况需要调用副本构造函数:
(1)明确表示由一个对象初始化另一个对象时;//其实这一点可用(2)来理解,本质上相同
(2)当对象作为函数实参传递给函数作形参时;
(3)当对象作为函数值进行返回时。
第二种情况正常理解即可,当对象作为参数传递给函数时,要创建该对象的“临时副本”,因此会调用副本构造函数,此时为了防止创建临时类对象的副本,常向函数传递类对象的“引用”;
第三种情况也是正常理解即可,当对象作为返回值时,系统会制作返回值的“副本”,且系统总会自动制作函数返回值的副本。
(1)程序仿真验证
#include<iostream>
using namespace std;
class B
{
private:
int data;
public:
B()
{
cout<<"defualt constructor"<<endl;
}
~B()
{
cout<<"destructed"<<endl;
}
B(int i):data(i)
{
cout<<"construted by parameter"<<data<<endl;
}
B(const B& copy)
{
cout<<"copy constructor is called."<<endl;
data = copy.data;
}
B& operator=(const B& b)
{
cout<<"the assignment operator overloading."<<endl;
data = b.data;
return *this;
}
};
B play(B b)
{
return b;
}
int main()
{
B b(500);
B temp;
temp = play(b);
return 0;
}
仿真结果:
(2)做些修改探讨一些其他的问题
#include<iostream>
using namespace std;
class B
{
private:
int data;
public:
B()
{
cout<<"defualt constructor"<<endl;
}
~B()
{
cout<<"destructed"<<endl;
}
B(int i):data(i)
{
cout<<"construted by parameter"<<data<<endl;
}
B(const B& copy)
{
cout<<"copy constructor is called."<<endl;
data = copy.data;
}
B& operator=(const B& b)
{
cout<<"the assignment operator overloading."<<endl;
data = b.data;
return *this;
}
};
B play(B b)
{
return b;
}
int main()
{
B b(500);
B temp = play(b); //此时不会调用重载的赋值运算符
return 0;
}
注意:若要按照前面调用三次副本构造函数的话则整段程序会调用4次析构函数。
int main()
{
}
(3)对程序又做了一些修改,看看结果如何
在(2)的基础上将main函数修改为
int main()
{
}
结果如下:
(4)再次修改(杂交以上所有的分析)
将(2)中的main函数修改为:
int main()
{
}
输出结果为:
分析: