封裝、構造函數、析構函數
1 封裝
①具體一點,封裝是將數據和行爲結合在一個包中,對對象的使用者隱藏數據的實現方式。
②實現封裝的關鍵:不能讓類中的方法直接訪問其他類的內部數據,只能通過公開行爲方法來間接訪問。
其實在上一節中已經提到過封裝的概念了。
將數據成員和成員函數包裝進類中,加上具體實現的隱藏,共同被稱作封裝,其結果是一個同時帶有特徵和行爲的數據類型。
信息隱藏是OOP最重要的功能之一,也是使用訪問修飾符的原因。
信息隱藏的原因包括:
①對模塊的人和實現細節所作的更改不會影響使用該模塊的代碼
②防止用戶意外修改數據
③使模塊易於使用和維護
2 構造函數
1、對象初始化
所有的變量都有一個初始狀態,對象的初始值由構造函數決定。
建立對象的同時,自動會調用構造函數。
2、構造函數的基本語法
構造函數和類名相同,沒有返回值
3、構造函數的初始化列表
一般使用初始化列表對數據成員進行初始化
4、構造函數的重載
一個類可以有多個構造函數
5、默認構造函數
不需要參數可以構造對象的函數叫做默認構造函數
首先建立一個類
class car
{
public:
//屬性初始化
car()
{
cout<<”car constructor”<<endl;
price=1;
weight=1;
sudu=0;
}
private:
int price;
int weight;
int sudu;
};
int main()
{
car Car;
cout<<Car.price<<" “<<Car.weight<<” "<<Car.sudu<<endl;
return 0;
}
如下 在用car類 定義一個對象Car時,會自動調用構造函數car()。
運行結:
car constructor
1 1 0
3 析構函數
1、對象的銷燬
在程序運行中,所有變量都要在合適的時機將對象銷燬,否則會影響程序性能
2、析構函數的基本概念
析構函數負責回收對象資源
3、析構函數的語法
析構函數和類名相同,在前面加上"~"
構造函數是定義一個對象的時候調用的,那麼析構函數在什麼時候調用的呢?
首先建立一個類
class car
{
public:
//屬性初始化
car()
{
cout<<" car constructor"<<endl;
}
~car()
{
cout<<" car destructor"<<endl;
}
private:
int price;
int weight;
int sudu;
};
當主函數爲:
int main()
{
car Car;
cout<<“main will be end”<<endl;
return 0;
}
運行結果:
car constructor
main will be end
car destructor
當主函數爲:
int main()
{
{
car Car;
}
cout<<“main will be end”<<endl;
return 0;
}
運行結果:
car constructor
當主函數爲:
int main()
{
car Car;
cout<<“main will be end”<<endl;
return 0;
}
運行結果:
car constructor
car destructor
main will be end
仔細觀察爲什麼結果不同,可以初步對比出析構函數的調用時機。對象的生命週期是從對它定義的時候開始,到它遇到第一個花括號結束,當對象的生命週期結束時,將調用析構函數。
注意:
①如果一個類沒有專門定義構造函數,那麼C++就僅僅創建對象而不做任何初始化
②如果類沒有自定義析構函數,則編譯器提供一個默認的析構函數
上期每次一練答案:
#include <stdio.h>
#include <string.h>
int main( )
{
char a[10] = “abc” ,b[10] = “012”,c[10] = “xyz”;
strcpy( a+1,b+2);
puts( strcat( a,c+1));
return 0;
}
輸出結果爲:a2yz
解析:
C語言標準庫函數strcpy,把從src地址開始且含有’\0’結束符的字符串複製到以dest開始的地址空間。。
從a[1]的地址開始,把b[2]開始的字符複製到a[1],當然字符串結束標誌也複製過去了。此時a[10] = “a2\0”;
strcat( a,c+1);這個就簡單多了。把c[1]開始的字符串接過去到a的屁股後面。。a[10]=“a2yz\0”;