深入理解四大函数:构造函数、拷贝构造函数、赋值函数、析构函数。
测试1:
#include<iostream>
using namespace std;
class Test{
public:
Test(int d = 0):data(d){
cout<<"Create Test Object:"<<this<<endl;
}
Test(const Test &t){
cout<<"Copy Create Test Object:"<<this<<endl;
data = t.data;
}
Test& operator=(const Test &t){
cout<<"Assign:"<<this<<"="<<&t<<endl;
if(this != &t){
data = t.data;
}
return *this;
}
~Test(){
cout<<"Free Test Object:"<<this<<endl;
}
public:
int GetData()const{
return data;
}
private:
int data;
};
Test fun(Test x){
int value = x.GetData();
Test tmp;
}
int main(){
Test t1(100);
Test t2;
t2 = fun(t1);
return 0;
}
结果:
理解:
构造函数:创建t1对象,30。
构造函数:创建t2对象,2C。
拷贝构造函数:调用fun函数,因为fun函数的参数是以对象的形式进行使用的,所以调用拷贝构造函数,C4。
构造函数:创建临时的tmp对象,A4。
拷贝构造函数:最终返回tmp,借助一个临时的无名对象,24。
析构函数:先析构tmp对象,再析构x对象。
赋值函数:fun函数返回的无名对象24给t2赋值,t2是2C。
析构函数:析构掉无名对象,24。
析构函数:析构掉t2对象,2C。
析构函数:最后析构掉t1对象,30。
测试2:
#include<iostream>
using namespace std;
class Test{
public:
Test(int d = 0):data(d){
cout<<"Create Test Object:"<<this<<endl;
}
Test(const Test &t){
cout<<"Copy Create Test Object:"<<this<<endl;
data = t.data;
}
Test& operator=(const Test &t){
cout<<"Assign:"<<this<<"="<<&t<<endl;
if(this != &t){
data = t.data;
}
return *this;
}
~Test(){
cout<<"Free Test Object:"<<this<<endl;
}
public:
int GetData()const{
return data;
}
private:
int data;
};
/*
//测试1
Test fun(Test x){
int value = x.GetData();
Test tmp(value);
return tmp;
}
*/
//测试2
Test fun(Test x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
int main(){
Test t1(100);
Test t2;
t2 = fun(t1);
return 0;
}
结果:
理解:
构造函数:创建t1对象,30。
构造函数:创建t2对象,2C。
拷贝构造函数:调用fun函数,因为fun函数的参数是以对象的形式进行使用的,所以调用拷贝构造函数,C4。
构造函数:创建无名临时对象,24。
析构函数:析构x对象,C4。
赋值函数:fun函数返回的无名对象24给t2赋值,t2是2C。
析构函数:析构掉无名对象,24。
析构函数:析构掉t2对象,2C。
析构函数:最后析构掉t1对象,30。
测试3:
#include<iostream>
using namespace std;
class Test{
public:
Test(int d = 0):data(d){
cout<<"Create Test Object:"<<this<<endl;
}
Test(const Test &t){
cout<<"Copy Create Test Object:"<<this<<endl;
data = t.data;
}
Test& operator=(const Test &t){
cout<<"Assign:"<<this<<"="<<&t<<endl;
if(this != &t){
data = t.data;
}
return *this;
}
~Test(){
cout<<"Free Test Object:"<<this<<endl;
}
public:
int GetData()const{
return data;
}
private:
int data;
};
/*
//测试1
Test fun(Test x){
int value = x.GetData();
Test tmp(value);
return tmp;
}
*/
/*
//测试2
Test fun(Test x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
*/
//测试3
Test fun(Test &x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
int main(){
Test t1(100);
Test t2;
t2 = fun(t1);
return 0;
}
结果:
理解:
构造函数:创建t1对象,30。
构造函数:创建t2对象,2C。
用了引用,所以不调用拷贝构造函数。
构造函数:创建无名临时对象,28。
赋值函数:fun函数返回的无名对象28给t2赋值,t2是2C。
析构函数:析构掉无名对象,28。
析构函数:析构掉t2对象,2C。
析构函数:最后析构掉t1对象,30。
测试4:
#include<iostream>
using namespace std;
class Test{
public:
Test(int d = 0):data(d){
cout<<"Create Test Object:"<<this<<endl;
}
Test(const Test &t){
cout<<"Copy Create Test Object:"<<this<<endl;
data = t.data;
}
Test& operator=(const Test &t){
cout<<"Assign:"<<this<<"="<<&t<<endl;
if(this != &t){
data = t.data;
}
return *this;
}
~Test(){
cout<<"Free Test Object:"<<this<<endl;
}
public:
int GetData()const{
return data;
}
private:
int data;
};
/*
//测试1
Test fun(Test x){
int value = x.GetData();
Test tmp(value);
return tmp;
}
*/
/*
//测试2
Test fun(Test x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
*/
/*
//测试3
Test fun(Test &x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
*/
//测试4
Test& fun(Test &x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
int main(){
Test t1(100);
Test t2;
t2 = fun(t1);
return 0;
}
结果:
理解:
构造函数:创建t1对象,30。
构造函数:创建t2对象,2C。
用了引用,所以不调用拷贝构造函数。
构造函数:创建无名临时对象,C4。
析构函数:紧接着析构无名临时对象,C4。
赋值函数:fun函数返回的无名对象C4给t2赋值,t2是2C。
析构函数:析构掉t2对象,2C。
析构函数:最后析构掉t1对象,30。
这种方法有一个很大的问题:就是不能起到赋值的作用。因为临时对象一创建就被析构了。但是如果把写的赋值语句注释掉,赋值就对了。自动执行内部的赋值函数。
测试5:
#include<iostream>
using namespace std;
class Test{
public:
Test(int d = 0):data(d){
cout<<"Create Test Object:"<<this<<endl;
}
Test(const Test &t){
cout<<"Copy Create Test Object:"<<this<<endl;
data = t.data;
}
Test& operator=(const Test &t){
cout<<"Assign:"<<this<<"="<<&t<<endl;
if(this != &t){
data = t.data;
}
return *this;
}
~Test(){
cout<<"Free Test Object:"<<this<<endl;
}
public:
int GetData()const{
return data;
}
private:
int data;
};
/*
//测试1
Test fun(Test x){
int value = x.GetData();
Test tmp(value);
return tmp;
}
*/
/*
//测试2
Test fun(Test x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
*/
/*
//测试3
Test fun(Test &x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
*/
/*
//测试4
Test& fun(Test &x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
int main(){
Test t1(100);
Test t2;
t2 = fun(t1);
return 0;
}
*/
//测试5
Test fun(Test &x){
int value = x.GetData();
return Test(value); //创建无名临时对象的语法
}
int main(){
Test t1(100);
Test t2 = fun(t1); //直接初始化
return 0;
}
结果:
理解:
构造函数:创建t1对象,30。
构造函数:创建的无名临时对象就是t2对象,2C。
析构函数:析构掉t2对象,2C。
析构函数:最后析构掉t1对象,30。
版权声明:本文为博主原创文章,如有错误,恳请大家在评论区指出,在下不胜感激~如要转载注明出处即可~