文章目錄
- 1. 建構式
- 1.1 建構式體賦值
- 1.2 初始化串列
- explicit關鍵字
- 2. static成員
- 2.1 概念
- 2.2 特性
- 3. C++11的成員初始化新玩法
- 4. 友元
- 4.1 概念
- 4.2 友元函式
- 4.3 友元類
- 5. 內部類
- 5.1 概念
- 5.2 特性
1. 建構式
1.1 建構式體賦值
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 初始化串列
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
注意:
1.每個成員變數在初始化串列中只能出現一次(初始化只能初始化一次)
2.類中包含以下成員,必須放在初始化串列位置進行初始化
(1)參考成員變數
(2)const成員變數
(3)自定義型別成員(該類沒有默認建構式)
class A
{
public:
A(int a)
:_a(a)
{}
private:
int _a;
};
class B
{
public:
B(int a, int ref)
:_aobj(a)
, _ref(ref)
, _n(10)
{}
private:
A _aobj;
int& _ref;
const int _n;
};
3.盡量使用初始化串列進行初始化,因為無論你是否使用初始化串列,對于自定義型別的成員變數一定會先用初始化串列初始化,
4.成員變數在類中宣告次序就是其初始化串列中的初始化順序,與其在初始化串列中的先后次序無關
explicit關鍵字
??建構式不僅可以構造與初始化物件,對于單個引數的建構式,還具有型別轉換的作用,用explicit修飾建構式,將會禁止單建構式的隱式轉換,
class Date
{
public:
Date(int year)
:_year(year)
{}
//有了就編不過了
/*explicit Date(int year)
:_year(year)
{}*/
private:
int _year;
int _month;
int _day;
};
void TestDate()
{
Date d1(2018);
d1 = 2019;
}
2. static成員
2.1 概念
??宣告為static的類成員稱為類的靜態成員,用static修飾的成員變數,稱之為靜態成員變數,用static修飾的成員函式,稱之為靜態成員函式,靜態的成員變數一定要在類外進行初始化,
2.2 特性
??1.靜態成員為所有類物件共享,不屬于某個具體的實體
??2.靜態成員變數必須在類外定義,定義時不添加static關鍵字
??3.類靜態成員即可用類名::靜態成員或者物件.靜態成員來訪問
??4.靜態成員函式沒有隱藏的this指標,因此不能訪問任何的非靜態成員
??5.靜態成員和類的普通成員一樣,也有public,protected,private3種訪問級別,也可以具有回傳值
問題:
1.靜態成員可以呼叫非靜態成員函式嗎?
??不可以,靜態成員函式沒有隱含的this指標,是所有類物件公有的一份而已
2.非靜態成員函式可以呼叫類的靜態成員函式嗎?
??可以
3. C++11的成員初始化新玩法
??C++11支持非靜態成員變數在宣告時進行初始化賦值,但是要注意這里不是初始化,這里是給宣告的成員變數預設值,
class B
{
public:
B(int b = 0)
:_b(b)
{}
int _b
};
4. 友元
4.1 概念
??友元分為友元函式和友元類,友元提供了一種突破封裝的方式,有的時候能提供便利,但是友元會增加耦合度,破壞封裝,所以不宜多用,
4.2 友元函式
??問題:現在我們嘗試去多載operator<<,然后我們發現不能將operator<<多載成成員函式,因為cont的輸出流物件和隱含的this指標在搶占第一個引數的位置,this指標默認時第一個引數也就是左運算元了,但是實際使用中cout需要是第一個形參物件,才能正常使用,所以我們要將operator<<多載成全域函式,但是這樣會導致類外沒有辦法訪問成員,那么這里就需要友元來解決,operator>>同理,
class Date
{
friend ostream& operator<<(ostream& _cout, const Date& d);
friend istream& operator>>(istream& _cin, 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;
}
istream& operator>>(istream& _cin, Date& d)
{
_cin >> d._year;
_cin >> d._month;
_cin >> d._day;
return _cin;
}
說明:
??1.友元函式可訪問類的私有和保護成員,但不是類的成員函式
??2.友元函式不能用const修飾
??3.友元函式可以在定義的任何地方宣告,不受類訪問限定符限制
??4.一個函式可以是多個類的友元函式
??5.友元函式的呼叫與普通函式的呼叫和原理相同
4.3 友元類
??友元類的所有成員函式都可以是另一個類的友元函式,都可以訪問另一個類中的非公有成員,
??友元關系是單向的,不具有交換性,A類中宣告B類為其友元類,那么B類中可以直接訪問A類的私有成員變數,但是A類不能訪問B類的私有成員變數,
??友元關系不具有傳遞性,如果B是A的友元,C是B的友元,則不能說明C時A的友元,
#include <iostream>
using namespace std;
//前置宣告
class Date;
class Time
{
friend class Date;
public:
Time()
{}
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 = 1900, int month = 1, int day = 1)
: _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;
};
5. 內部類
5.1 概念
??如果一個類的定義在另一個類的內部,那么這個內部的類就叫做內部類,此時這個內部類是一個獨立的類,它不屬于外部類,更不能通過外部類的物件去呼叫內部類,外部類對內部類沒有任何優越的訪問權限,
注意:
??內部類就是外部類的友元類,注意友元類的定義,內部類可以通過外部類的物件引數訪問外部類中的所有成員,但是外部類不是內部類的友元,
5.2 特性
??1.內部類可以定義在外部類的public,protected,private都是可以的,
??2.注意內部類可以直接訪問外部類中的static,列舉成員,不需要外部類的物件/類名,
??3.sizeof(外部類)=外部類,和內部類沒有任何關系,
#include <iostream>
using namespace std;
class A
{
private:
static int k;
int h;
public:
class B
{
public:
void foo(const A& a)
{
cout << k << endl;
cout << a.h << endl;
}
};
};
int A::k = 1;
int main()
{
A::B b;
b.foo(A());
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/277078.html
標籤:其他
