1. 程式人生 > >C++類和物件學習筆記(3)

C++類和物件學習筆記(3)

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、private3種訪問級別,也可以具有返回值const修飾符等引數
  • 內部類就是在類內定義一個類,內部類是外邊類的友元類