一.初始化列表
1.引入
我們知道在c++11中才能在成員對(duì)象聲明時(shí)初始化,像下面這樣。
class Date
{
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
private:
int _year=2000;
int _month=12;
int _day=20;
};
注意:構(gòu)造函數(shù)不是初始化,而是賦初始值。那么在c++11以前該怎么初始化成員變量呢?
2.初始化列表登場(chǎng)
- 每個(gè)成員變量在初始化列表中只能出現(xiàn)一次(初始化只能初始化一次)
- 類中包含以下成員,必須放在初始化列表位置進(jìn)行初始化:
引用成員變量
const成員變量
自定義類型成員(且該類沒有默認(rèn)構(gòu)造函數(shù)時(shí))–默認(rèn)構(gòu)造函數(shù)對(duì)于內(nèi)置類型不處理,自定義類型調(diào)用它的默認(rèn)構(gòu)造函數(shù)。(默認(rèn)構(gòu)造不用傳參就能調(diào)用的)
3.盡量使用初始化列表初始化,因?yàn)椴还苣闶欠袷褂贸跏蓟斜?,?duì)于自定義類型成員變量,一定會(huì)先使用初始化列表初始化(不管是否顯示在初始化列表寫,每個(gè)變量都會(huì)先走初始化列表)- 成員變量在類中聲明次序就是其在初始化列表中的初始化順序,與其在初始化列表中的先后次序無關(guān)
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; // 沒有默認(rèn)構(gòu)造函數(shù)
int& _ref; // 引用
const int _n; // const
};
3.explicit關(guān)鍵字
3.1一個(gè)例子
按理來說這里aa2應(yīng)該是1先調(diào)用構(gòu)造生成一個(gè)A類型的1,再拷貝構(gòu)造給aa2。(單參數(shù)的構(gòu)造函數(shù)會(huì)發(fā)生隱式類型轉(zhuǎn)換)然而卻只調(diào)用了構(gòu)造,原因是編譯器發(fā)生了優(yōu)化
那么如何避免這種隱式類型的轉(zhuǎn)換呢?就需要用到explicit關(guān)鍵字。
可以看到加上explicit就會(huì)報(bào)錯(cuò),編譯器阻止了這種隱式類型轉(zhuǎn)換
3.2概念
1.指定構(gòu)造函數(shù)或轉(zhuǎn)換函數(shù) (C++11起)為顯式, 即它不能用于隱式轉(zhuǎn)換和復(fù)制初始化.
2.explicit 指定符可以與常量表達(dá)式一同使用. 函數(shù)若且唯若該常量表達(dá)式求值為 true 才為顯式. (C++20起)
3.3何時(shí)使用
Effective C++中也寫:
被聲明為explicit的構(gòu)造函數(shù)通常比其 non-explicit 兄弟更受歡迎, 因?yàn)樗鼈兘咕幾g器執(zhí)行非預(yù)期 (往往也不被期望) 的類型轉(zhuǎn)換. 除非我有一個(gè)好理由允許構(gòu)造函數(shù)被用于隱式類型轉(zhuǎn)換, 否則我會(huì)把它聲明為explicit. 我鼓勵(lì)你遵循相同的政策.
二.static
1.概念
聲明為static的類成員稱為類的靜態(tài)成員,用static修飾的成員變量,稱之為靜態(tài)成員變量;用static修飾的成員函數(shù),稱之為靜態(tài)成員函數(shù)。靜態(tài)成員變量一定要在類外進(jìn)行初始化。靜態(tài)成員屬于類共有的,而不是某個(gè)實(shí)例化對(duì)象的。
2.統(tǒng)計(jì)一個(gè)類創(chuàng)建多少個(gè)類對(duì)象
class A
{
public:
A()
{
_count++;
}
A(const A& aa)
{
_count++;
}
static int GetCount()
{
return _count;
}
private:
static int _count;
};
int A::_count = 0;
int main()
{
A aa1;
A aa2(aa1);
A aa3(aa1);
cout << A::GetCount() << endl;
}
如果沒加private,可以直接通過對(duì)象訪問或指定類域訪問
A::_count;
aa2._count;
A*ptr=nullptr;
ptr->_count;
3.特性
- 靜態(tài)成員為所有類對(duì)象所共享,不屬于某個(gè)具體的對(duì)象,存放在靜態(tài)區(qū)
- 靜態(tài)成員變量必須在類外定義,定義時(shí)不添加static關(guān)鍵字,類中只是聲明
- 類靜態(tài)成員即可用 類名::靜態(tài)成員 或者 對(duì)象.靜態(tài)成員 來訪問
- 靜態(tài)成員函數(shù)沒有隱藏的this指針,不能訪問任何非靜態(tài)成員
- 靜態(tài)成員也是類的成員,受public、protected、private 訪問限定符的限制
三.友元
友元提供了一種突破封裝的方式,有時(shí)提供了便利。但是友元會(huì)增加耦合度,破壞了封裝,所以友元不宜多用。
1.友元函數(shù)
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;
}
友元函數(shù)可訪問類的私有和保護(hù)成員,但不是類的成員函數(shù)
友元函數(shù)不能用const修飾
友元函數(shù)可以在類定義的任何地方聲明,不受類訪問限定符限制
一個(gè)函數(shù)可以是多個(gè)類的友元函數(shù)
友元函數(shù)的調(diào)用與普通函數(shù)的調(diào)用原理相同
2.友元類
友元類的所有成員函數(shù)都可以是另一個(gè)類的友元函數(shù),都可以訪問另一個(gè)類中的非公有成員。
友元類不能繼承
友元類不能傳遞
友元類是單向的文章來源:http://www.zghlxwxcb.cn/news/detail-808723.html
四.拷貝構(gòu)造優(yōu)化
1.接收返回對(duì)象,盡量拷貝構(gòu)造方式接收,不要賦值接收。
2.函數(shù)中返回對(duì)象是,盡量返回匿名對(duì)象。文章來源地址http://www.zghlxwxcb.cn/news/detail-808723.html
到了這里,關(guān)于4.【CPP】入門(初始化列表||explicit||static||友元||靜態(tài)成員變量/函數(shù))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!