1、構造函數分類
按參數類型:分爲無參構造函數和有參構造函數
按類型分類:普通構造函數和拷貝構造函數(複製構造函數)
2、構造函數的調用
class Data
{
public:
int num;
public:
//構造函數(無參的構造)
Data()
{
num = 0;
cout<<"無參的構造函數 num = "<<num<<endl;
}
//構造函數(有參的構造)
Data(int n)
{
num = n;
cout<<"有參的構造函數 num = "<<num<<endl;
}
//析構函數(沒有返回值類型 沒有參數 不能重載)
~Data()
{
cout<<"析構函數 num = "<<num<<endl;
}
};
void test02()
{
//調用無參 或 默認構造 (隱式調用)
Data ob1;
//調用無參構造 (顯示調用)
Data ob2 = Data();
//調用有參構造(隱式調用)
Data ob3(10);
//調用有參構造(顯示調用)
Data ob4 = Data(20);
//隱式轉換的方式 調用有參構造(針對於 只有一個數據成員)(儘量別用)
Data ob5 = 30;//轉化成Data ob5(30)
//匿名對象(當前語句結束 匿名對象立即釋放)
Data(40);
cout<<"------"<<endl;
//千萬不要 用一下方式調用 無參構造
}
運行結果:
注意:在同一作用域 構造和析構的順序相反
3、拷貝構造函數(系統提供一個拷貝構造函數 賦值操作)
//拷貝構造函數
Data(const Data &ob)//const Data &ob = ob1
{
//拷貝構造函數 是ob2調用 num就是ob2的num
//ob2.num = ob1.num
num = ob.num;
cout<<"拷貝構造"<<endl;
}
void test03()
{
Data ob1(10);
cout<<"ob1.num = "<<ob1.num<<endl;
//調用拷貝構造函數(如果用戶 不實現拷貝構造 系統將調用默認的拷貝構造)
//默認的拷貝構造:單純的整體賦值(淺拷貝)
//如果用戶實現了 拷貝構造 系統將調用用戶實現的拷貝構造
Data ob2(ob1);//隱式調用拷貝構造函數
cout<<"ob2.num = "<<ob2.num<<endl;
Data ob3 = Data(ob1);//顯示調用拷貝構造函數
cout<<"ob3.num = "<<ob3.num<<endl;
Data ob4 = ob1;//=隱式轉換調用
cout<<"ob4.num = "<<ob4.num<<endl;
}
運行結果:
記住一句話:舊對象 初始化 新對象 纔會調用拷貝構造函數
Data ob1(10);
Data ob2(ob1);//拷貝構造
Data ob3 = Data(ob1);//拷貝構造
Data ob4 = ob1;//拷貝構造函數
注意:下方的就不會調用拷貝構造
Data ob1(10);
Data ob2;
ob2 = ob1;//不會調用拷貝構造 單純對象 賦值操作
案例:
void test04()
{
Data ob1(10);//調用有參構造
Data ob2;//調用無參構造
ob2 = ob1;//對象的賦值
cout<<"ob1.num = "<<ob1.num<<endl;
cout<<"ob2.num = "<<ob2.num<<endl;
}
運行結果:
4、拷貝構造函數的注意事項:
1、不能調用拷貝構造函數去初始化匿名對象,也就是說以下代碼不正確
2、對象作爲函數的參數 如果實參與形參 都是普通對象 那麼就會調用拷貝構造
3、函數返回局部對象 在qt中會被優化 從而調用不了拷貝構造