六种构造函数的实现代码如下:
#include<iostream>
using namespace std;
//c++中六种默认的构造函数
class Test
{
public:
Test(int d = 0):m_data(d)//1构造函数(带默认值0),以参数列表的形式初始化
{
cout<<"Creat Test Obj :"<<this<<endl;
}
~Test()//2析构函数
{
cout<<"Free Test Obj :"<<this<<endl;
}
Test(const Test &t)//3拷贝构造函数:以对象初始化对象
{
cout<<"Copy Test Obj :"<<this<<endl;
m_data = t.m_data;
}
Test& operator=(const Test &t)//4赋值语句
{
cout<<"Assgin:"<<this<<":"<<&t<<endl;
if(this != &t)
{
m_data = t.m_data;
}
return *this;
}
Test* operator&()//5对象取址
{
return this;
}
const Test* operator&()const//6常对象取址
{
return this;
}
int GetData()
{
return m_data;
}
private:
int m_data;
};
下面介绍9种情况下构造函数的调用过程:
情况一:
//1
Test fun(Test t)
{
int value = t.GetData();
Test tmp(value);
return tmp;
}
int main()
{
Test t(10);
Test t1;
t1 = fun(t);
return 0;
}
情况二:
//2
Test fun(Test t)
{
int value = t.GetData();
return Test(value);
}
int main()
{
Test t(10);
Test t1;
t1 = fun(t);
return 0;
}
情况三:
//3
Test fun(Test &t)
{
int value = t.GetData();
Test tmp(value);
return tmp;
}
int main()
{
Test t(10);
Test t1;
t1 = fun(t);
return 0;
}
情况四:
//4
Test fun(Test &t)
{
int value = t.GetData();
return Test(value);
}
void main()
{
Test t(10);
Test t1;
t1 = fun(t);
}
情况五:
//5
Test& fun(Test &t)
{
int value = t.GetData();
Test tmp(value);
return tmp;
}
void main()
{
Test t(10);
Test t1;
t1 = fun(t);
}
情况六:
//6
Test& fun(Test &t)
{
int value = t.GetData();
return Test(value);
}
void main()
{
Test t(10);
Test t1;
t1 = fun(t);
}
情况七:
//7
Test fun(Test &t)
{
int value = t.GetData();
return Test(value);
}
void main()
{
Test t(10);
Test t1 = fun(t);
}
情况八:
//8
Test fun(Test &t)
{
int value = t.GetData();
Test tmp(value);
return tmp;
}
void main()
{
Test t(10);
Test t1 = fun(t);
}
情况九:
Test& fun(Test &t)
{
int value = t.GetData();
Test tmp(value);
return tmp;
}
void main()
{
Test t(10);
Test t1;
t1 = fun(t);
}
综上所述:
一:调用拷贝构造函数的情况:
1)直接用对象初始化对象
2)形参数对象时,用实参对象初始化
3)函数的返回值类型是类时(非引用)是,拷贝构造无名的临时空间作为函数返回值
二:注意:
当函数的返回值是该函数中的一个临时对象时,函数类型不可以定义为Test &即引用,否则会发生,用一个已经析构的临时对象初始化另外一个对象,会发生错误;
三:提高效率的方式:
1)形参用引用,不再调用拷贝构造函数
2)返回一个无名的临时对象a,系统不再创建另外的一个临时对象而直接将a作为返回值,(函数返回类型不是引用)
3)返回无名的临时对象,且用它初始化另外一个对象,如情况七,直接将无名的对象作为另外的一个对象
4)上述三种情况结合;