緒論
????????時間的步伐有三種:未來姍姍來遲,現(xiàn)在像箭一樣飛逝,過往永遠(yuǎn)靜立不動。本章是類和對象的一個收尾篇,相信通過這三篇類和對象的學(xué)習(xí),應(yīng)該你已經(jīng)更加清楚了解了C++的類和對象。
![]()
話不多說安全帶系好,發(fā)車?yán)?strong>(建議電腦觀看)。
附:紅色,部分為重點部分;藍(lán)顏色為需要記憶的部分(不是死記硬背哈,多敲);黑色加粗或者其余顏色為次重點;黑色為描述需要
思維導(dǎo)圖:
要XMind思維導(dǎo)圖的話可以私信哈
目錄
1.再談構(gòu)造函數(shù)
1.1初始化列表
1.2:explicit? ?
2.static
3.友元
3.2友元類
4.內(nèi)部類
5.匿名對象
1.再談構(gòu)造函數(shù)
知識點:
前面我們已經(jīng)學(xué)習(xí)過來構(gòu)造函數(shù),他是用來給對我們的成員進(jìn)行初始化的。如:
Date(int year = 1970, int month = 1, int day = 1) { _year = year; _month = month; _day = day; }
而因為在一些特殊的情況下,構(gòu)造函數(shù)無法完成一些活動,所以不能只使用構(gòu)造函數(shù)
因此C++又提出了一個新概念:
1.1初始化列表
知識點:
如像:引用、const變量 (他們都是需要在定義的時候進(jìn)行初始化,否則就無法正常的使用)、以及自定義類型(當(dāng)沒有默認(rèn)構(gòu)造函數(shù)的時)他們都不能直接通過構(gòu)造函數(shù)來完成
?
在一個對象定義的時候其成員變量是在初始化列表中進(jìn)行定義的
語法:?
基本和構(gòu)造函數(shù)差不多,在其中間插入初始化列表
Date(...)
????????:成員變量(初始值/變量)
????????,??成員變量(.....)
????????....
????????,成員變量(.....)
{
? ? ? ? ......
}
并且對于成員變量來說,其在c++11打的補(bǔ)丁,可以給成員缺省值,實際上就是把這個個缺省值給初始化列表
?實例如下:
class B { public: /*B() { _a = 1; }*/ B(int a) :_a(a) { _a = a; } private: int _a; }; class A { public: A(int& a, int i) //而對于成員的初始化是在初始化列表處完成的 :_a(a) , _i(1) ,bb(10)//此時因為沒有默認(rèn)構(gòu)造,所以我們只能去調(diào)用構(gòu)造函數(shù),所以需要我們使用初始化列表來進(jìn)行傳參 ,a()//內(nèi)置類型 { } private: //對于引用和常變量來說他們必須在定義的時候進(jìn)行初始化,否則就無法使用 int& _a; const int _i; //而對于自定義結(jié)構(gòu)來說,也是通過初始化列表來進(jìn)行初始化的 B bb; //內(nèi)置類型的缺省值,其實就是給初始化列表的 int a = 1; }; int main() { int n = 0; A(n,10); return 0; }
細(xì)節(jié):
- 對于初始化列表,當(dāng)你不寫時,操作系統(tǒng)也會默認(rèn)的生成一個,并且肯定會走初始化列表過一下
- 對于構(gòu)造函數(shù)來說,初始化列表固然很強(qiáng)能解決大部分初始化時的定義問題,但不能完全解決是有問題
- 對于自定義結(jié)構(gòu)來說也是同理他會自動去通過初始化列表來進(jìn)行調(diào)用自身的構(gòu)造函數(shù),但是如果是內(nèi)置類型當(dāng)不給缺省值/不在構(gòu)造函數(shù)內(nèi)賦值的話,他并不會自動的初始化
- 成員變量是通過 聲明的順序進(jìn)行初始化 的和初始化列表的順序無關(guān)
- 對于4來說,我們就建議聲明的順序和定義的順序保持一致
練習(xí):
通過初始化列表讓沒有默認(rèn)構(gòu)造的自定義類型可以進(jìn)行初始化(此時有的是非默認(rèn)構(gòu)造的構(gòu)造函數(shù))。
1.2:explicit? ?
在對于下面這種代碼來說,是存在隱式類型轉(zhuǎn)換的
A a = 3; const A& a = 3;
并且在編譯器下會把構(gòu)造+構(gòu)造這種在一行的多次構(gòu)造的情況優(yōu)化成只進(jìn)行一次構(gòu)造
假如是分開行就不行了
假如我們不想讓其可以進(jìn)行隱式類型轉(zhuǎn)換的話,就可以在構(gòu)造函數(shù)全面加上explicit
使用后就會標(biāo)紅
2.static
知識點:
概念:聲明為static的類成員稱為類的靜態(tài)成員,用static修飾的成員變量,稱之為靜態(tài)成員變量;用static修飾的成員函數(shù),稱之為靜態(tài)成員函數(shù)。靜態(tài)成員變量一定要在類外進(jìn)行初始化,此處他并不是每個類對象的成員變量,而是每個對象共享的一個變量
語法:在變量/函數(shù)前面加上static
初始化需要再類外面進(jìn)行,具體如下:
class A { public: A(int a)//并且不能在構(gòu)造中初始化 { } private: int _a; static int _b;//聲明 }; int A::_b = 0;//初始化 int main() { return 0; }
不能在類內(nèi)部定義
細(xì)節(jié):
為了防止我們可以隨意的更改_b , 所以一般會把_b放到私有里面。
此時就只能通過在類里面創(chuàng)建一個獲取函數(shù)/創(chuàng)建友元函數(shù)來 獲取里面的_b了
對于獲取函數(shù)來說,我們也一般習(xí)慣寫成靜態(tài)的,當(dāng)把函數(shù)也寫成靜態(tài)的時候,此時這個函數(shù)時沒有this指針的,就只能通過通類靜態(tài)成員即可用 類名::靜態(tài)成員 或者 對象.靜態(tài)成員 來訪問
。static int GetB()//一般我們會把這個定義成靜態(tài)的函數(shù),此時是沒有this指針的,指定類域和訪問限定符就能進(jìn)行訪問該函數(shù) { return _b; } //訪問: //cout << a.GetB() << endl; cout << A::GetB() << endl;
注意,因為在靜態(tài)函數(shù)中沒有this指針,所以不能去調(diào)用成員變量/成員函數(shù),而在成員函數(shù)中卻可以去調(diào)用靜態(tài)的函數(shù),如果一定需要去使用成員函數(shù),則需要傳進(jìn)來,并且需要在參數(shù)部分接收
類靜態(tài)成員即可用 類名::靜態(tài)成員 或者 對象.靜態(tài)成員 來訪問
靜態(tài)成員也是類的成員,受public、protected、private 訪問限定符的限制
?
練習(xí):
設(shè)計一個類,在類外面只能在棧上創(chuàng)建對象
設(shè)計一個類,在類外面只能在堆上創(chuàng)建對象
class A { public: static A GetStack() { A a; return a;//返回創(chuàng)建的對象 } static A* GetHeap() { return new A;//new一個空間給A } private: A() {} private: int _a = 0; int _b = 1; }; int main() { //此時沒有別的辦法就只能用靜態(tài)函數(shù) //因為構(gòu)造函數(shù)也屬于私有的,所以我們不能直接定義一個對象 A::GetStack(); A::GetHeap(); return 0; }
3.友元
知識點:
友元提供了一種突破封裝的方式,有時提供了便利。但是友元會增加耦合度(關(guān)聯(lián)性),破壞了封裝,所以友元不宜多用。
友元分為:友元函數(shù)和友元類
細(xì)節(jié):
3.1友元函數(shù)
在前面的 operator <<、operator >> 處我們已經(jīng)使用過了,是用來讓函數(shù)可以使用一個類中的成員變量
語法:friend 函數(shù)聲明
- 友元函數(shù)可以訪問類的私有成員,它是定義在類外部的普通函數(shù),不屬于任何類,但需要在類的內(nèi)部聲明,聲明時需要加friend關(guān)鍵字。
- 友元函數(shù)不能用const修飾(因為其沒有this指針)
- 友元函數(shù)可以在類定義的任何地方聲明,不受類訪問限定符限制
- 一個函數(shù)可以是多個類的友元函數(shù)
3.2友元類
友元類的所有成員函數(shù)都可以是另一個類的友元函數(shù),都可以訪問另一個類中的非公有成員
(和友元函數(shù)一樣,當(dāng)我們在一個類中定義了另外一個友元的類對象,此時在另外的那個類中就能去使用聲明的類中的成員變量)具體寫法:friend class 類名
練習(xí)使用:
class B {
friend class A;
private:
int _b = 10;
};
class A {
public:
A()
{}
void Print()
{
//此時創(chuàng)建一個B類的對象就能去訪問其類內(nèi)的私有
cout << _i._b << endl;
}
private:
int _a = 0;
B _i;
};
int main()
{
A a;
a.Print();
return 0;
}
4.內(nèi)部類
知識點:
一個類定義在另一個類的內(nèi)部,這個內(nèi)部類就叫做內(nèi)部類
細(xì)節(jié):
- 內(nèi)部類是外部類的友元類,所以說在內(nèi)部類可以使用外部類的成員變量,但是外部類卻不能使用內(nèi)部類的成員變量,所以說我們可以直接把,內(nèi)部類的成員變量寫在外部,這樣就能一起使用了。
- 內(nèi)部類同樣是受public、protected、private訪問限定符的限制,當(dāng)寫成私有時類外面也無法直接使用
練習(xí)使用:
還有寫許細(xì)節(jié)已經(jīng)進(jìn)行了注釋
class A {
public:
class B {//此時的B就是A的一個內(nèi)部類,并且內(nèi)部類時外部類的友元,可以使用外部類的變量
public:
B()
{}
void Print(const A& a)//注意也并不是直接就能使用其成員變量,還是需要先實例化一個對象的
{
cout << a._a << a._b << endl;
}
private:
};
private:
int _a = 0;
int _b = 10;
};
int main()
{
A a;
A::B b;//當(dāng)是public 時就能在外部定義了
return 0;
}
class A {
public:
class B {//此時的B就是A的一個內(nèi)部類,并且內(nèi)部類時外部類的友元,可以使用外部類的變量
public:
B()
{
}
void Print()
{
cout << _a <<_b << endl;//此處對于靜態(tài)成員來說直接通過A::xxx 就能訪問,所以對在A類內(nèi)的B就能直接使用靜態(tài)的
}
private:
};
private:
static int _a;
static int _b;
};
int main()
{
A a;
A::B b;//當(dāng)是public 時就能在外部定義了
return 0;
}
5.匿名對象
知識點:
匿名對象,其是就是創(chuàng)建一個沒有對象名的對象,并且此時匿名對象在創(chuàng)建行構(gòu)造,到下一行時就會析構(gòu)。
匿名對象的創(chuàng)建方法: 類名 ();
匿名對象的使用方法:類名() . 調(diào)用的函數(shù);
細(xì)節(jié):
- 匿名對象和臨時變量一樣都具有常性,所以要引用這個對象的話需要加上const來修飾
- 如const A& ra = A();
- 并且對于被引用的匿名對象來說,他的生命周期也會因為被引用而延長到該局部函數(shù)結(jié)束時
- 附:在創(chuàng)建對象的時候不能寫成 如? ?Date d();? ? 因為此時編譯器無法分清這是函數(shù)的聲明還是你對象的構(gòu)造,所以對于不傳參的情況不用加上括號
具體練習(xí):
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 Sum_Solution(int n) {
//...
return n;
}
};
int main()
{
A aa1;//正常的構(gòu)造
A();//匿名對象,生命周期在本行
A aa2(2);//正常的構(gòu)造
Solution().Sum_Solution(10);//匿名對象調(diào)用其函數(shù),并且此處并不會調(diào)用構(gòu)造函數(shù)
const A& ra = A();//注意匿名對象具有常性,所以需要在引用前面+const
A aa3(3);//正常的構(gòu)造
return 0;
}
本章完。預(yù)知后事如何,暫聽下回分解。
如果有任何問題歡迎討論哈!
如果覺得這篇文章對你有所幫助的話點點贊吧!文章來源:http://www.zghlxwxcb.cn/news/detail-458106.html
持續(xù)更新大量C++細(xì)致內(nèi)容,早關(guān)注不迷路。文章來源地址http://www.zghlxwxcb.cn/news/detail-458106.html
到了這里,關(guān)于C++ 類和對象(靜態(tài)的static、友元、內(nèi)部類、匿名對象、explicit)知識點+完整思維導(dǎo)圖+實操圖+深入細(xì)節(jié)通俗易懂建議收藏的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!