C++類和物件學習筆記(3)
阿新 • • 發佈:2018-12-18
1.初始化列表
a.建構函式體賦值
在建立物件
時,編譯器可以通過呼叫建構函式
,給物件中各個成員變數一個合適的初始值
。但是雖然建構函式呼叫之後,物件中已經有了一個初始值,但是不能將其稱作為類物件成員的初始化
,建構函式體中的語句只能將其稱作為賦初值
,而不能稱作初始化
。因為初始化只能初始化一次
,而建構函式體內 可以多次賦值
b.初始化列表
以一個冒號:
開始,接著是一個以逗號,分隔的資料成員列表
,每個"成員變數"
後面跟一個放在括 號中的初始值或表示式
。
class Date
{
public:
//初始化列表
Date(int year, int month, int day)
:_year(year)
, _month(month)
, _day(day)
{}
private:
int _year;
int _month;
int _day;
};
初始化列表的特點:
- 每個成員變數在初始化列表中只能出現一次
(初始化只能初始化一次)
- 成員變數在類中
宣告次序就是其在初始化列表中的初始化順序
,與其在初始化列表中的先後次序無關 (很重要)
//_size首先是個隨機值,可能開闢空間會失敗,因為_size的宣告在後,先初始化arr,size現在還是隨機值
class array{
public:
array(int size=10){
:_size(size);
,arr((int*)mallco(sizeof(int)*_size));
}
private:
int* arr;
int _size;
}
- 儘量
避免
使用成員初始化成員
- 類中包含以下成員,一定要放在
初始化列表
位置進行初始化,因為它們必須要在宣告的時候初始化
1.const修飾的成員變數
2.引用成員變數
3.類型別成員(該類有非預設的構造)
2.建構函式作用
建構函式
不僅可以構造與初始化物件
,對於單個引數的建構函式
,還具有型別轉換的作用
。
class Date
{
public:
explicit Date(int year)
: _year(year)
{}
private:
int _year;
int _month:
int _day;
};
int main()
{
Date d1(2018);//建構函式
Date d2=d1;//拷貝建構函式
//用一個整形變數給日期型別物件賦值
Date d3=2019;//具有單引數建構函式的類可以強制轉換,相當於Date tem(2019)->d3(tmp);
// 實際編譯器背後會用2019構造一個無名物件,最後用無名物件給d1物件進行賦值
}
注:上述程式碼可讀性不是很好,用explicit
修飾建構函式,將會禁止單參建構函式的隱式轉換
。
2.友元
a.友元函式
友元函式可以直接訪問類的私有成員
,它是定義在類外部的普通函式
,不屬於任何類,但需要在類的內部宣告
,宣告時需要加friend關鍵字
。
class Date
{
friend ostream& operator<<(ostream& _cout, const Date& d);
public:
Date(int year, int month, int day)
:_year(year)
,_month(month)
,_day(day)
{}
private:
int _year;
int _month;
int _day;
};
//運算子過載,友元函式可以直接訪問類內私有成員
ostream& operator<<(ostream& _cout, const Date& d)
{
_cout << d._year << "-" << d._month << "-" << d._day;
return _cout;
}
int main()
{
Date d(2018, 10, 28);
cout << d << endl;
return 0;
}
注意點:
- 友元函式可訪問類的私有成員,但不是類的成員函式
- 友元函式不能用const修飾
- 友元函式可以在類定義的任何地方宣告,不受類訪問限定符限制
- 一個函式可以是多個類的友元函式
- 友元函式的呼叫與普通函式的呼叫和原理相同
b.友元類
友元類
的所有成員函式
都可以是另一個類的友元函式
,都可以訪問另一個類中的非公有成員
。
c.友元的優缺點
- 優點:提高了程式執行效率
- 缺點:破壞了類的封裝性和隱藏性
- 友元關係是單向的,不具有交換性。
- 友元關係不能傳遞
3.static成員
宣告為static的類成員
稱為類的靜態成員
,用static修飾的成員變數
,稱之為靜態成員變數
;用static修飾的成員函式
,稱之為靜態成員函式
。靜態的成員變數一定要在類外進行初始化
面試題:怎麼可以確定一個類建立了多少個物件
class Count
{
public:
Count()
{
num++;
}
Count(Count& c)
{
num++;
}
static int getNum()
{
return num;
}
private:
static int num;
};
//類外定義
int Count::num = 0;
int main()
{
cout << Count::getNum() << endl;//0
Count c;
Count c2(c);
cout << Count::getNum() << endl;//2
}
b.static成員的特性
- 靜態成員為所有
類物件所共享
,不屬於某個具體的例項
- 靜態成員變數必須在
類外定義
,定義時不新增static關鍵字 - 類靜態成員即可用類名
::
靜態成員或者物件.靜態成員
來訪問 - 靜態成員函式
沒有隱藏的this指標
,不能訪問任何非靜態成員
- 靜態成員和類的普通成員一樣,也有
public、protected、private
3種訪問級別,也可以具有返回值
,const修飾符
等引數 內部類
就是在類內定義一個類,內部類是外邊類的友元類
。