C++程式設計學習筆記 複習/拾遺 2
建構函式與物件初始化
建構函式用於建立類物件,初始化其成員。
解構函式用於撤銷類物件。
物件的私有資料成員初始化
若物件定義時若未顯式初始化,與變數類似,全域性物件和靜態物件在定義時初值為0,區域性物件在定義時初值為不確定的值。一旦建立一個物件,物件通常都需要有一個有意義的初值。
1.在類中定義一個具有初始化功能的成員函式。每當建立一個物件時,就呼叫這個成員函式,實現初始化。
例項
#include <iostream> using namespace std; class computer//計算器類定義 {//預設訪問許可權是私有 int op1;//運算元 char ch;//運算子 int op2;//運算元 public: void Set(int b,char d,int c) { op1=b; ch=d; op2=c;} void Show(); void Init() {op1=3; ch='+';op2=5; } }; void computer::Show()//成員函式類外定義 { switch(ch) { case '+':cout<<op1+op2<<endl;break; case '-':cout<<op1-op2<<endl;break; case '*':cout<<op1*op2<<endl;break; case '/':if(op2==0) cout<<"不能被0除"<<endl; else cout<<op1/op2<<endl; break; default:cout<<"運算子有錯"<<endl; } } int main() { computer a;//定義物件 a.Init();//通過成員函式進行物件初始化 a.Show();//計算並輸出結果 return 0; }
void Init()
{op1=3; ch='+';op2=5; }
computer a;//定義物件
a.Init();//通過成員函式進行物件初始化
2.建立物件的同時,自動呼叫建構函式,省去上述麻煩,使定義類物件時包含了為物件分配儲存空間和初始化的雙重任務。這種實現機制較為理想。
由於類的唯一性和物件的多樣性,因此C++ 規定建構函式與類同名。其特點是:
①建構函式的作用是在物件被建立時使用特定的值構造物件,或者說將物件初始化為一個特定的狀態。
②在物件建立時由系統自動呼叫。
③如果程式中未宣告,則系統自動產生出一個預設形式的建構函式。
④建構函式可以有引數,也可過載。可以為行內函數、過載函式、帶預設形參值的函式。
⑤建構函式無返回型別,但是不要加void。
C++ 規定,每一個類必須有一個建構函式,沒有建構函式就不能建立任何物件。
若未定義一個類的建構函式,則C++ 提供了一個預設的建構函式,該預設建構函式是一個無引數的建構函式,僅僅負責建立物件,而不做任何初始化工作;
只要一個類定義了一個建構函式,C++ 就不再提供預設的建構函式。如還需要無引數建構函式,則必須自己定義;
與變數定義類似,在用預設建構函式建立物件時,如果建立的是全域性物件或靜態物件,則物件成員資料全為0;區域性物件建立時,其成員資料是無意義的隨機數。
例項
#include <iostream> using namespace std; class computer//計算器類定義 {//預設訪問許可權是私有 int op1;//運算元 char ch;//運算子 int op2;//運算元 public: void Set(int b,char d,int c) { op1=b; ch=d; op2=c; } void Show(); computer(int b,char d,int c) {op1=b; ch=d;op2=c; } }; void computer::Show()//成員函式類外定義 { switch(ch) { case '+':cout<<op1+op2<<endl;break; case '-':cout<<op1-op2<<endl;break; case '*':cout<<op1*op2<<endl;break; case '/':if(op2==0) cout<<"不能被0除"<<endl; else cout<<op1/op2<<endl; break; default:cout<<"運算子有錯"<<endl; } } int main() { computer a(3,'+',5);//定義物件並初始化 a.Show();//計算並輸出結果 return 0; }
computer(int b,char d,int c)
{op1=b; ch=d;op2=c; }
computer a(3,'+',5);//定義物件並初始化
注意:建構函式可採用以下兩種方式將值賦給其成員。
1、在建構函式體內進行成員變數的賦值,如例3.2所示,
computer(int b,char d,int c)
{ op1=b; ch=d; op2=c; //在函式體內賦值
}
2、使用函式體前的初始值表,例如:
computer(int b,char d,int c):op1(b),ch(d),op2(c){ }
this指標
在每個類的成員函式中,都隱含了一個this 指標,該指標指向正在呼叫成員函式的物件。如下所示:
computer(int op1,char ch,int op2)
{this->op1=op1;
this->ch=ch;
this->op2=op2;
}
computer建構函式中:3個形參與資料成員同名,所以使用this指標進行區別。如果不同名,可以不用this指標進行區分。類的其他成員函式碰到形參與資料同名的情況,也用this指標進行同樣的區分。
無參建構函式進行物件初始化的例項
#include <iostream>
using namespace std;
class computer//計算器類定義
{//預設訪問許可權是私有
int op1,op2;//兩個運算元
char ch;//運算子
public:
void Set(int b,char d,int c)
{ op1=b;op2=c;ch=d; }
void Show();
computer(int b,char d,int c)//帶參建構函式
{op1=b;ch=d;op2=c; }
computer()//無參建構函式
{op1=3;ch='+';op2=5; }
};
//建構函式過載。C++ 根據物件定義時所帶引數型別和個數選擇合適的建構函式
void computer::Show()//成員函式類外定義
{switch(ch)
{case '+':cout<<op1+op2<<endl;break;
case '-':cout<<op1-op2<<endl;break;
case '*':cout<<op1*op2<<endl;break;
case '/':if(op2==0) cout<<"不能被0除"<<endl;
else cout<<op1/op2<<endl;
break;
default:cout<<"運算子有錯"<<endl;
}
}
int main()
{
computer a(9,'/',2),b;//定義物件並初始化
//如果要定義一個不帶引數的物件b,則會呼叫無參建構函式完成物件初始化的工作
a.Show();//計算並輸出結果
b.Show();//計算並輸出結果
return 0;
}
函式過載:
一組引數和返回值不同的函式共用一個函式名。
注意: 過載函式之間必須在引數的型別或個數方面有所不同。只有返回值型別不同的幾個函式不能過載。
int add(int x, int y);
形參型別不同
float add(float x, float y);
int add(int x, int y);
形參個數不同
int add(int x, int y, int z);
注意:由於類名是成員函式名的一部分,所以一個類的成員函式與另一個類的成員函式即使同名,也不認為是過載,因為不同作用域。
過載函式的形參必須不同: 個數不同或型別不同。編譯程式將根據實參和形參的型別及個數的最佳匹配來選擇呼叫哪一個函式。
不要將不同功能的函式宣告為過載函式,以免出現呼叫結果的誤解、混淆。
帶預設形參值的函式
函式定義時,可在形參列表中預先給一些預設值
當呼叫這種函式時,若為相應引數給出實參,則用實參初始化對應形參;如果沒給出,則自動採用預先給定的預設形參值。
注意:
要保證所有的預設引數均放在引數表的最後,即預設引數值必須按從右向左的順序宣告。如:
void func(int x, int n1 = 1, int n2 = 2);
預設形參值與函式的呼叫位置
調用出現在函式體實現之前時,預設形參值必須在函式原形中給出;而當調用出現在函式體實現之後時,預設形參值需在函式實現時給出。
帶預設值建構函式進行物件初始化
#include <iostream>
using namespace std;
class computer//計算器類定義
{//預設訪問許可權是私有
int op1,op2;//兩個運算元
char ch;//運算子
public:
void Set(int b,char d,int c)
{ op1=b;op2=c;ch=d; }
void Show();
computer(int b=3,char d='+',int c=5)//帶預設值的建構函式
{op1=b;ch=d;op2=c; }
};
//帶參建構函式和無參建構函式可以合併定義,用一個帶預設值的建構函式定義即可
void computer::Show()//成員函式類外定義
{switch(ch)
{case '+':cout<<op1+op2<<endl;break;
case '-':cout<<op1-op2<<endl;break;
case '*':cout<<op1*op2<<endl;break;
case '/':if(op2==0) cout<<"不能被0除"<<endl;
else cout<<op1/op2<<endl;
break;
default:cout<<"運算子有錯"<<endl;
}
}
int main()
{ computer a(9,'/',2),b(9,'/'),c(9),d;//定義物件並初始化
a.Show();//計算並輸出結果9/2=4
b.Show();//計算並輸出結果9/5=1
c.Show();//計算並輸出結果9+5=14
d.Show();//計算並輸出結果 3+5=8
return 0;
}