類與物件3
注:這是一篇補充部落格。
一、建構函式補充;
1.建構函式體賦值:
在建立物件時,編譯器通過呼叫建構函式,給物件中每個成員一個合適的初始值。
class Date
{
public:
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
雖然上述建構函式呼叫之後,物件中已經有了一個初始值,但是不能將其稱為類物件成員的初始化,建構函式體中的語句只能將其稱為賦初值,不能作為初始化,因為初始化只能有一次,但是建構函式體中可以多次賦值。所以就牽扯到下面一種初始化方式。
2.初始化列表
class Date
{
public:
Date(int year, int month, int day)
: _year(year)
,_month(month)
,_day(day)
{}
private:
int _year;
int _month;
int _day;
};
初始化列表:以一個“:”開始,用“,”分隔開資料成員列表,每個成員變數後跟一個“()”用來放初始值或者表示式。
需要注意的是:
(1).還是和建構函式賦值一樣,因為他們都可以賦值多次,而初始化只能有一次,所以初始化列表也只能在建構函式中出現一次。
(2).必須使用初始化列表的幾種情況:
a.引用成員變數;
b.const成員變數;
c.類型別成員(該類沒有預設建構函式)。
(3).一般儘量使用初始化列表。
3.explicit關鍵字(重點)
建構函式不僅可以構造與初始化物件,對於單個引數的建構函式,還具有型別轉換的作用,而explicit關鍵字就是阻止這種型別轉換的。
用explicit關鍵字修飾建構函式,將會禁止單參建構函式的隱式轉換。
二、static成員
1。概念:
宣告為static的類成員稱為類的靜態成員,用static修飾的成員變數,稱之為靜態成員變數;用static修飾的成員函式,稱之為靜態成員函式。靜態的成員變數一定要在類外進行初始化。
2.特點:
(1)靜態成員為所有類物件共享,不屬於某個具體的例項;
(2)靜態成員變數必須在類外定義,定義時不加static關鍵字;
(3)類靜態成員即可用類名:靜態成員或者物件那個,靜態成員來訪問;
(4)靜態成員函式沒有隱藏的this指標,不能訪問任何非靜態成員;(任何非靜態成員都可以訪問靜態成員,但是靜態成員不可以訪問任何非靜態成員)
(5)靜態成員和類的普通成員一樣,也有public、protected\private3種訪問級別,也可以具有返回值,const修飾符等引數。
三、友元
友元分為友元函式和友元類。
1.友元函式:
class Date { public: Date(int year, int month, int day) : _year(year) ,_month(month) ,_day(day) {} ostream& operator << (ostream& _cout) { _cout << d._year << " " << d._month << " " << d._day << endl; return _cout; } private: int _year; int _month; int _day; }; int main() { Date d(2018,11,17); d << cout; return 0; }
在這段程式碼種就能體現出來,我們要過載operator << ,但是發現,cout的輸出流物件和隱含的this指標在搶佔第一個引數的位置,this指標預設是第一個引數也就是左操作數了。但是實際種cout需要第一個形參物件,才能正常使用。所以我們就要將operator<<過載成全域性函式,但是這樣的話又會導致類外沒辦法訪問成員。
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 << endl;
return _cout;
}
int main()
{
Date d(2018,11,17);
cout << d << endl;
return 0;
}
友元函式就可以直接訪問類的私有成員,他是定義在類外的普通函式,不屬於任何類,但需要在類的內部宣告,宣告時需要加關鍵字friend。
注意:友元函式可訪問類的私有成員,但不是類的成員函式
友元函式不能用const修飾
友元函式可以在類定義的任何地方宣告,不受類訪問限定符限制
一個函式可以是多個類的友元函式
友元函式的呼叫與普通函式的呼叫和原理相同
2、友元類
友元類的所有成員函式都可以是另一個類的友元函式,都可以訪問另一個類中的非公有成員。
友元類關係時單向的,不具有交換性;
友元關係不能傳遞。
class Date;
class Time
{
friend class Date;
public:
Time(int hour, int minute, int second)
: _hour(hour)
, _minute(minute)
, _second(second)
{}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year = 2018, int month = 11, int day = 17)
: _year(year)
, _month(month)
, _day(day)
{}
void SetTimeOfDate(int hour, int minute, int second)
{
_t._hour = hour;
_t._minute = minute;
_t._second = second;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
怎麼區分誰是誰的友元類:
可以象徵的認為你和你的酒肉朋友一樣,他可以肆無忌憚的讓你請他吃飯,而卻不會請你吃飯,他就相當於你的友元類。