關于構造函數的認識:在建立一個對象時,常常需要做某些初始化工作,例如如何給數據成員賦初值。如果一個數據成員未被賦值,則他的值是不可預知的,因為系統在為它分配內存時,保留了這些存儲單元的原狀,這就成為了數據成員的初始值。這種情況顯然是與人們的要求不相符的,對象是一個實體,它反映了客觀事物的屬性,是應該有確定值的。
但是數據成員是不能在聲明類時初始化
如例1、
class Data{ int year=2; int month=12; int day=31;};為什么不能在不能在聲明類時對數據成員初始化?
因為類并不是一個實體,而是一種抽象的數據類型,并不占存儲空間,顯然無法容納數據。
如果一個類中所有的成員都是公用的,則可以在定義對象時對數據成員進行初始化。
例2、
class Data{public: int year=2; int month=12; int day=31;};構造函數的作用:構造函數是一種特殊的成員函數,與其他成員函數不同。不需要用戶來調用它,而是在創建類對象時,由編譯器自動調用。構造函數的名字與類名相同,而不能由用戶任意命名,以便編譯系統能識別它并把它作為構造函數處理 。它不具有任何類型,也沒有返回值。構造函數的功能是由用戶自己定義的,用戶根據初始化的要求設計函數體和函數參數。例3、
class Time{public: Time() { hour = 0; minute = 0; second = 0; } void setTime(); void showTime();PRivate: int hour; int minute; int second;};int main(){ Time t; t.setTime(); t.showTime(); system("pause"); return 0;}void Time::setTime(){ cin >> hour; cin >> minute; cin >> second;}void Time::showTime(){ cout << hour << ":" << minute << ":" << second << endl;}我們可以看出在這個程序里定義了一個構造函數,在建立對象時自動執行構造函數,它的作用是為該對象中的各數據成員賦初值0。程序運行時首先建立對象t,并對t中的數據成員賦初值0,然后再執行setTime()函數,從鍵盤輸入新值給對象t中的數據成員,再執行showTime()函數輸出數據成員的值。
帶參數的構造函數:
在上面的例子我們可以看出這個構造函數是不帶參數的,在函數體中對個數據成員賦初值。這種方式使該類的每一個對象都得到同一組初值。但是用戶有時希望對不同的對象賦予不同的初值,這時就需要我們采用帶參數的構造函數
構造函數名(類型1形參1,類型2形參2....)
前面我們可以知道用戶是無法調用構造函數的,因此無法采用常規的調用函數的方法給出實參如fun(a,b)。實參是定義對象時給出的,定義對象的一般格式為:
類名 +對象名(實參1,實參2)
例4、有連個長方柱,其長寬高分別為:(1)12,25,30(2)15,30,21分別求他們的體積。
class Box{public: Box(int a, int b, int c)//構造函數名(類型1形參1,類型2形參2....) { length= a; width = b; hight = c; } int value() { return (length*width*hight); }private: int length; int width; int hight;};int main(){ Box t1(12,25,30), t2(15,30,21);//類名 + 對象名(實參1,實參2) cout << "the result1 is :" << t1.value() << endl; cout << "the result2 is :" << t2.value() << endl; system("pause"); return 0;}
用參數初始化列表對數據成員初始化
在構造函數的函數體內通過賦值語句對數據成員實現初始化,C++還提夠另一種初始化數據成員的方法------參數初始化列表來實現對數據成員的初始化。這種方法不在函數體內對數據成員初始化,而是在函數首部實現
例如將上述例子中定義的構造函數可以修改成如下形式:
class Box{public: Box(int a, int b, int c);//構造函數名(類型1形參1,類型2形參2....) int value() { return (length*width*hight); }private: int length; int width; int hight;};Box::Box(int a, int b, int c)//構造函數名(類型1形參1,類型2形參2....) :length(a) , width(b) , hight(c) {} /*length = a; width = b; hight = c;*/int main(){ Box t1(12,25,30), t2(15,30,21);//類名 + 對象名(實參1,實參2) cout << "the result1 is :" << t1.value() << endl; cout << "the result2 is :" << t2.value() << endl; system("pause"); return 0;}構造函數的重載‘例5、class Box{public: Box(); Box(int a, int b, int c) //構造函數名(類型1形參1,類型2形參2....) :length(a) , width(b) , hight(c) { }//在類體中直接定義構造函數 int value() { return (length*width*hight); }private: int length; int width; int hight;};//Box::Box(int a, int b, int c)//構造函數名(類型1形參1,類型2形參2....)// :length(a)// , width(b)// , hight(c)// {////} /*length = a; width = b; hight = c;*/Box::Box(){ hight = 10; width = 10; length = 10;}int main(){ Box t3; cout << "the result3 is :" << t3.value() << endl; Box t1(12,25,30), t2(15,30,21);//類名 + 對象名(實參1,實參2) cout << "the result1 is :" << t1.value() << endl; cout << "the result2 is :" << t2.value() << endl; system("pause"); return 0;}第一個構造函數是沒有參數的,是在類體外直接對數據成員進行賦值的。第二個構造函數是直接在類體內定義的。這兩個構造函數進行了重載說明:在調用構造函數時不必給出實參的構造函數稱為默認的構造函數或者缺省構造函數。
一個類只能有一個默認的構造函數,否則系統就無法辨別應該執行哪個構造函數。
構造函數是不能被用戶顯式調用的
盡管在一個類中可以有多個構造函數,但是對每一個對象來說,建立對象時只執行一個構造函數并非每個構造函數都被執行。
使用默認參數的構造函數:
構造函數中參數的值既可以進行實參傳遞,也可以制定某些默認值,即如果用戶不指定實參值 ,編譯系統就使形參取默認值。
例6、將構造函數改用默認值的參數、長、寬、高的默認值均為10 。
#include<iostream>#include<stdlib.h>using namespace std;class Box{public: Box(int h = 10, int w = 10, int len = 10);//在聲明構造函數時指定默認參數 int volume();private: int height; int width; int length;};Box::Box(int h, int w, int len)//在類體外定義構造函數 :height(h) ,width(w) , length(len){ }int Box::volume(){ return(height*width*length);}int main(){ Box box1; cout << "the value of box1 is " << box1.volume() << endl;//沒有給定實參系統就調用默認的構造函數值都是10 Box box2(15); cout << "the value of box1 is" << box2.volume() << endl;//給定了一個實參,它就傳給形參,未得到實參的就取默認值 Box box3(15,20); cout << "the value of box1 is" << box3.volume() << endl;//同理 Box box4(15, 20, 30); cout << "the value of box1 is" << box4.volume() << endl; system("pause"); return 0;}說明:應該在聲明構造函數時指定默認值,而不應該在定義構造函數時指定默認值。
在聲明構造函數的時候,形參名可以省略。
如果一個構造函數的的全部形參都指定了默認值,則在定義一個對象時可以不給出實參也可以給出幾個實參
一個類只能有一個默認的構造函數,一個構造函數的的全部形參都指定了默認值也是默認的構造函數,
如上述例子。 .
新聞熱點
疑難解答