C++中的構造函數小結

對象的初始化

對象時類的實例,類是不佔用空間的,對象是佔用空間的。

因爲類是抽象的,不佔用空間的,所以我們不能再定義類的時候對對象進行初始化操作的。

但是,我們可以定義一個函數,在類實例化一個對象的時候,對對象賦初值,這個函數就叫做構造函數

構造函數是類在定義對象的時候,自動執行的對對象中的數據進行初始化操作的函數。

構造函數的作用

構造函數不同於其他的函數,不需要用戶調用它(用戶也不可以調用這個函數),而是在建立對象時自動執行的。構造函數的名字必須與類名相同,以便編譯系統能識別它並把它作爲構造函數處理。

它不具有任何類型,不返回任何值。構造函數的功能是由用戶定義的,用戶根據初始化的要求設計函數體和函數參數。

===================例子1===================================

#include<iostream>
using namespace std;
class Time{
	public:
		Time(){//定義構造函數,注意函數名必須與類名相同
			hour=10;
			minute=10;
			sec=10;
		}
		void set_time();
		void show_time();
	private:
		int hour;
		int minute;
		int sec;
};
void Time::set_time(){
	cout<<"hour :";
	cin>>hour;
	cout<<"minute :";
	cin>>minute;
	cout<<"sec :";
	cin>>sec;
}
void Time::show_time(){
	cout<<"Time : "<<hour<<":"<<minute<<":"<<sec<<endl;
}
int main(){
	Time t1;
	t1.show_time();
	cout<<"======================="<<endl;
	Time t2;
	t2.set_time();
	t2.show_time();
}

當然,構造函數也可以在類外定義:

#include<iostream>
using namespace std;
class Time{
	public:
		Time();
		void set_time();
		void show_time();
	private:
		int hour;
		int minute;
		int sec;
};
Time::Time(){//注意構造函數是沒有返回值的
			hour=10;
			minute=10;
			sec=10;
 }
void Time::set_time(){
	cout<<"hour :";
	cin>>hour;
	cout<<"minute :";
	cin>>minute;
	cout<<"sec :";
	cin>>sec;
}
void Time::show_time(){
	cout<<"Time : "<<hour<<":"<<minute<<":"<<sec<<endl;
}
int main(){
	Time t1;
	t1.show_time();
	cout<<"======================="<<endl;
	Time t2;
	t2.set_time();
	t2.show_time();
}
構造函數的聲明和定義與其他的函數是有區別的,它沒有返回值。


構造函數的3個特點:


1.函數的調用是在類對象進入其作用域時自動調用的。

2.構造函數沒有返回值,因此也不需要在定義構造函數時聲明類型,這是它和一般函數的一個重要的不同之處。

不能寫成:


否則會報錯

3.構造函數不需要用戶調用,也不能被用戶調用。

這樣寫是錯誤的:

否則會報錯

構造函數是在建立對象時由系統自動執行的,而且只能執行一次。

構造函數一般聲明爲public,若聲明成private就會報錯。



帶參數的構造函數

上面介紹的構造函數雖然可以初始化對象,但是用來初始化的值都是一樣的,這顯然不符合實際情況。

帶參數的構造函數就是用來解決這個問題的,它可以實現在調用不同對象的時候,用不同的值進行初始化。

一般格式是:

構造函數名(類型1 形參1,類型2 形參2,……)

構造函數的第三個特點是它不能採用常規的調用函數的方法給出實參(如,fun(a,b)),

實參是在定義對象時給出的,定義對象的一般格式是:

類名 對象名(實參1,實參2,……)

也就是說,它是在定義對象的時候進行傳值的。

=========================例子2==============================

有兩個長方體,其長寬高分別是:(1)12,20,25(2)10,14,20。分別求它們的體積

#include<iostream>
using namespace std;
class Box{
	public:
		Box(int,int,int);//聲明帶參數的構造函數
		int volume();//聲明求體積的函數
       private:
		int height;
		int width;
		int length;
};
Box::Box(int h,int w,int l){//定義帶參數的構造函數
	height=h;
	width=w;
	length=l;
}
int Box::volume(){//定義求體積的函數
	int z;
	z=height*width*length;
	return z;
}
int main(){
	Box b1(10,10,10);
	cout<<"Volume of b1 : "<<b1.volume()<<endl;
	Box b2(10,20,30);
	cout<<"Volume of b2 : "<<b2.volume()<<endl;
	return 0;
}

可以知道:

(1)帶參數的構造函數中的形參,其對應的實參在定義對象時給定。

(2)用這種方法可以方便地實現對不同的對象進行不同的初始化。

用參數初始化表對數據成員初始化

這種煩好伐不在函數體內對數據成員初始化,而是在函數首部實現。

  1. Box::Box(int h,int w,int l):height(h),width(w),length(l){}  
Box::Box(int h,int w,int l):height(h),width(w),length(l){}

即,在原來函數首部的末尾加一個冒號,然後列出參數的初始化表。

上面的初始化表表示:用形參h的值初始化數據成員height;用形參w的值初始化數據成員width;用形參l的值初始化數據成員。

這種寫法更加方便,簡單,尤其當需要初始化的數據成員較多的時候,更顯其優越性~

然而,很多時候,我們不僅需要不同的對象的初始化值不同,有些時候我們還想要使用默認的一些初始化值。

有兩種方法可以實現:

構造函數的重載

在一個類中定義多個構造函數,以便對類對象提供不同的初始化方法,供用戶選用。這些構造函數具有相同的名字,而參數的個數或參數的類型不同。

#include<iostream>
using namespace std;
class Box{
	public:
		Box(int,int,int);//含參數的構造函數
		Box();//不含參數的構造函數
		int volume();
	private:
		int height;
		int width;
		int length;
};
Box::Box(){
	height=0;
	width=0;
	length=0;
}
Box::Box(int h,int w,int l):height(h),width(w),length(l){}
int Box::volume(){
	int z;
	z=height*width*length;
	return z;
}
int main(){
	Box b1;//實例化對象的時候沒有進行傳值
	cout<<"Volume of b1 : "<<b1.volume()<<endl;
	Box b2(10,20,30);//實例化對象的時候進行傳值
	cout<<"Volume of b2 : "<<b2.volume()<<endl;
	return 0;
}


編譯系統是根據函數調用(在類實例化對象的時候自動進行)的時候,是否傳值,以及傳值的個數和類型進行判斷的。

(1)調用構造函數的時候,不必給出實參的構造函數,成爲默認構造函數(或稱爲缺省構造函數)。

顯然,無參構造函數屬於默認構造函數,而且一個類只能定義一個默認構造函數。

(2)儘管在一個類中可以包含多個構造函數,但是對於每一個對象來說,建立對象時只執行其中一個構造函數,並非每個構造函數都被執行。

使用默認參數的構造函數

#include<iostream>
using namespace std;
class Box{
	public:
		Box(int h=1,int w=1,int l=1);//含默認參數的構造函數
		int volume();
	private:
		int height;
		int width;
		int length;
};
Box::Box(int h,int w,int l):height(h),width(w),length(l){}
int Box::volume(){
	int z;
	z=height*width*length;
	return z;
}
int main(){
	Box b1;
	cout<<"Volume of b1 : "<<b1.volume()<<endl;
	Box b2(10,20,30);
 	cout<<"Volume of b2 : "<<b2.volume()<<endl;
	return 0;
}

(1)默認參數可以在聲明構造函數的時候指定,也可以在定義構造函數的時候指定

  1. Box::Box(int h=1,int w=1,int l=1):height(h),width(w),length(l){}  
Box::Box(int h=1,int w=1,int l=1):height(h),width(w),length(l){}

(2)在聲明構造函數的時候,形參名可以省略,即簡寫成:

  1. Box(int =1,int =1,int =1);//含參數的構造函數  
Box(int =1,int =1,int =1);//含參數的構造函數

(3)如果構造函數的全部參數都指定了默認值,則在定義對象時可以給定一個或者幾個實參,也可以不給出實參。

  1. Box b2(10,20);  
Box b2(10,20);

對應的結果是200

前面說了,不需要實參也可以調用的構造函數成爲缺省構造函數,並且,一個類只能有一個缺省構造函數,也就是說可以不使用參數而調用的構造函數,一個類只能有一個。

其道理是顯然的,因爲缺省構造函數不唯一的話,編譯系統就不知道在實例化對象的時候,沒有傳遞實參的情況下,應該調用哪一個函數了。

發佈了0 篇原創文章 · 獲贊 17 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章