文章目錄
- 二、static成員
- 概念
- 面試題
- 一個題目
- 三、友元
- 友元函數
- 說明
- 友元類
- 四、內部類(了解)
- 概念:
- 注意:
- 特性:
- 五、匿名對象
書接上回: 【C++】類和對象(五)隱式類型轉換
二、static成員
01_31 03 12 01
概念
聲明為static的類成員稱為類的靜態成員,用static修飾的成員變量,稱之為靜態成員變量;用static修飾的成員函數,稱之為靜態成員函數。靜態成員變量一定要在類外進行初始化
面試題
實現一個類,計算程序中創建出了多少個類對象。
class A
{
public:A() { ++_scount; }A(const A& t) { ++_scount; }~A() { --_scount; }//static成員函數沒有this指針static int GetACount() { return _scount; }
private://聲明 //靜態成員變量 不是屬于某一個對象,屬于所有對象,屬于整個類static int _scount;
};//定義
int A::_scount = 0;void TestA()
{cout << A::GetACount() << endl;A a1, a2;A a3(a1);cout << A::GetACount() << endl;
}
static 成員變量
使用場景:既想定義成全局的,又想用類封裝起來
static 成員函數
想訪問靜態的成員變量,那就可以提供一個靜態的成員函數
一個題目
02_01 000455
static成員應用
求1+2+3+…+n
思路:使用變長數組創建n個sum對象,借用構造函數 讓構造函數被調用n次 以此累加求和
定義一個sum類,類里面聲明靜態成員變量(相當于就是全局的,屬于整個類)。
三、友元
友元函數
問題:現在嘗試去重載operator<<,然后發現沒辦法將operator<<重載成成員函數。因為cout的輸出流對 象和隱含的this指針在搶占第一個參數的位置。this指針默認是第一個參數也就是左操作數了。但是實際使用 中cout需要是第一個形參對象,才能正常使用。所以要將operator<<重載成全局函數。但又會導致類外沒辦 法訪問成員,此時就需要友元來解決。operator>>同理。
class Date{public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}// d1 << cout; -> d1.operator<<(&d1, cout); 不符合常規調用// 因為成員函數第一個參數一定是隱藏的this,所以d1必須放在<<的左側ostream& operator<<(ostream& _cout){_cout << _year << "-" << _month << "-" << _day << endl;return _cout;}private:int _year;int _month;int _day;};
友元函數可以直接訪問類的私有成員,它是定義在類外部的普通函數,不屬于任何類,如果要成為一個類的朋友就需要在該類內部聲明,聲明時需要加friend關鍵字
class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
public:Date(int year = 1900, int month = 1, int day = 1): _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;
}
int main()
{Date d;cin >> d;cout << d << endl;return 0;
}
說明
友元函數可訪問類的私有和保護成員,但不是類的成員函數 友元函數不能用const修飾 友元函數可以在類定義的任何地方聲明,不受類訪問限定符限制 一個函數可以是多個類的友元函數 友元函數的調用與普通函數的調用原理相同
友元類
友元類的所有成員函數都可以是另一個類的友元函數,都可以訪問另一個類中的非公有成員。
友元關系是單向的,不具有交換性。
比如上述Time類和Date類,在Time類中聲明Date類為其友元類,那么可以在Date類中直接訪問Time 類的私有成員變量,但想在Time類中訪問Date類中私有的成員變量則不行。
友元關系不能傳遞 如
果B是A的友元,C是B的友元,則不能說明C時A的友元。
友元關系不能繼承。
class Time
{friend class Date;// 聲明日期類為時間類的友元類,則在日期類中就直接訪問Time類中的私有成員變量
public:Time(int hour = 0, int minute = 0, int second = 0): _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;
};
四、內部類(了解)
概念:
如果一個類定義在另一個類的內部,這個內部類就叫做內部類。內部類是一個獨立的類,它不屬于外部類,更不能通過外部類的對象去訪問內部類的成員。外部類對內部類沒有任何優越的訪問權限。
注意:
內部類就是外部類的友元類,內部類可以通過外部類的對象參數來訪問外部類中的所有成員。但是外部類不是內部類的友元。
特性:
- 內部類可以定義在外部類的public、protected、private都是可以的。
- 注意內部類可以直接訪問外部類中的static成員,不需要外部類的對象/類名。
- sizeof(外部類)=外部類,和內部類沒有任何關系。
class A
{
public://B這個類受A類的類域的限制class B{private:int _b1;};
private:int _a1;int _a2;
};
int main()
{cout << sizeof(A) << endl;A aa;A::B bb;return 0;
}
五、匿名對象
class A
{
public:A(int a=0):a(_a){cout << "A(int a)" <<endl;}~A(){cout <<"~A()" <<endl;}
private:int _a;
}
class Solution
{
public:int func(int n) {//...return n;}
};
int main()
{//有名對象A aa1;A aa2(10);//匿名對象//生命周期只在當前一行,,我們可以看到下一行他就會自動調用析構函數A();A(10);//匿名對象在這樣場景下就很好用:Solution sl;sl.func(10);//該匿名對象的誕生只是為了調用Sum_Solution(10)這個函數Solution().func(10);return 0;
}
匿名對象生命周期只有一行,我們可以看到走完匿名對象這一行立馬調用析構函數