1. 再談構(gòu)造函數(shù)
為赤峰等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及赤峰網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站制作、網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、赤峰網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!1.1構(gòu)造函數(shù)體賦值
在創(chuàng)建對象時,編譯器通過調(diào)用構(gòu)造函數(shù),給對象中給個成員變量一個合適的初始值。
class Date
{
public:
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
雖然上述構(gòu)造函數(shù)調(diào)用之后,對象中已經(jīng)有了一個初始值,但是不能將其稱為類對象成員的初始化, 構(gòu)造函數(shù)體中的語句只能稱為賦初值。 因為初始化只能初始化一次,二構(gòu)造函數(shù)體內(nèi)可以多次賦值。
1.2 初始化列表
初始化列表:以一個冒號開始,接著是一個以逗號分隔的數(shù)據(jù)成員列表, 每個“成員變量”后面跟一個放在括號中的初始值或表達式。
Date
{
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
private:
int _year;
int _month;
int _day;
};
【注意】
1. 每個成員變量在初始化列表中只能出現(xiàn)一次(初始化只能一次)
2. 類中包含以下成員, 必須放在初始化列表位置進行初始化:
√? ?引用成員變量
√? ?const成員變量
√? ?自定義類型成員(該類沒有默認構(gòu)造函數(shù))
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; //沒有默認構(gòu)造函數(shù)
int& _ref; //引用
const int _n; //const
};
3.盡量使用初始化列表初始化, 因為不管你是否使用初始化列表, 對于自定義類型成員變量, 一定會先使用初始化列表初始化。
class Time
{
public:
Time(int hour = 0)
:_hour(hour)
{
cout<< "Time()"<< endl;
}
privite:
int _hout;
};
class Date
{
public:
Date(int day)
{}
private:
int _day;
Time _t;
};
int main()
{
Date d(1);
};
4. 成員變量在類中聲明次序就是其在初始化列表中的初始化順序, 與其在初始化列表中的先后次序無關(guān)
clas A
{
public:
A(int a)
:_a1(a)
,_a2(_a1)
{}
void Print()
{
cout<< _a1<< " "<< _a2<< endl;
}
private:
int _a2;
int _a1;
};
int main()
{
A aa(1);
aa.Print();
}
A. 輸出1 1
B. 程序崩潰
C. 編譯不通過
D. 輸出1 隨機值
這題D是正確答案,按照聲明順序,先初始化_a2, 再初始化_a1.??
1.3 explicit關(guān)鍵字
構(gòu)造函數(shù)不僅可以構(gòu)造出初始化對象,對于單個參數(shù)的構(gòu)造函數(shù), 還具有類型轉(zhuǎn)換的作用。
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);
//用一個整型變量給日期類型對象賦值
//實際編譯器背后會構(gòu)造一個無名(匿名)對象,最后用 無名對象給d1對象進行賦值
d1 = 2019;
}
用explicit修飾構(gòu)造函數(shù), 將會禁止單參構(gòu)造函數(shù)的隱式轉(zhuǎn)換。
2.? static成員
2.1 概念
? 聲明為static的類成員稱為類的靜態(tài)成員 , 用static修飾的成員變量, 稱之為靜態(tài)成員變量; 用 static修飾的成員函數(shù), 稱之為靜態(tài)成員函數(shù)。 靜態(tài)的成員變量一定要在類外進行初始化
面試題: 實現(xiàn)一個類,計算程序中創(chuàng)建了多少個類對象。
class A
{
public:
A() { ++_scount; }
A(const A& t) { ++_scount; }
static int GetACount() { return _scount; }
private:
static int _scount;
};
int A::_scount = 0;
void TestA()
{
cout<< A::GetACount()<< endl;
A a1, a2; //這里實例化兩個對象a1, a2 , 直接構(gòu)造。
A a3(a1); //這里拷貝構(gòu)造a3
cout<< A::GetACount()<< endl;
}
int main()
{
TestA();
return 0;
}
2.2 特性
1. 靜態(tài)成員為所有類對象所共享, 不屬于某個具體的實例
2. 靜態(tài)成員變量必須在類外定義, 定義時不添加static關(guān)鍵字
3. 類靜態(tài)成員即可用類名::靜態(tài)成員或者對象, 靜態(tài)成員來訪問
4. 靜態(tài)成員函數(shù)沒有隱藏的this指針, 不能訪問任何非靜態(tài)成員
5. 靜態(tài)成員和類的普通成員一樣, 也有Public、protected、private 3種訪問級別,也可以具有返回值
【問題】
1. 靜態(tài)成員函數(shù)可以調(diào)用非靜態(tài)成員函數(shù)么??
不可以, 因為靜態(tài)成員函數(shù)沒有this指針。
2. 非靜態(tài)成員函數(shù)可以調(diào)用類的靜態(tài)成員函數(shù)么?
可以, 因為靜態(tài)成員函數(shù)在靜態(tài)區(qū), 為所有類對象共享。
3. C++11的成員初始化新玩法
C++11支持非靜態(tài)成員變量在聲明時進行初始化賦值, 但是要注意這里不是初始化,這里是給聲明的成員變量缺省值
class B
{
public:
B(int b = 0)
:_b(b)
{}
int _b;
};
class A
{
public:
void Print()
{
cout<< a<< endl;
cout<< b._b<< endl;
cout<< p<< endl;
}
private:
int a = 10;
B b = 20; //這里如果沒給值,就會是調(diào)用B的構(gòu)造函數(shù),默認是0
int* p = (int*)malloc(4);
static int n;
};
int A::n = 10;
int main()
{
A a;
a.Print();
return 0;
}
4. 友元
友元分為: 友元函數(shù)和友元類
友元提供了一種突破封裝的方式,有時提供了便利。但是友元增加耦合度,破環(huán)了封裝,所以友元不建議多用。
4.1 友元函數(shù)
問題: 現(xiàn)在我們嘗試取重載operator<< , 然后發(fā)現(xiàn)我們沒辦法將 operator<< 重載成員函數(shù)。因為cout的輸出流對象和隱含的this指針在搶占第一個參數(shù)的位置。 this指針默認是第一個參數(shù)也就是左操作數(shù)了。但是實際使用中cout需要時第一個形參對象, 才能正常使用。 所以我們要將operator<<重載成全局函數(shù)。 但是這樣的話,又會導(dǎo)致類外沒辦法訪問成員, 那么這里就需要友元來解決。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;
}
int main()
{
Date d(1,1,1);
cin >>d;
cout<< d<< endl;
return 0;
}
說明:
4.2 友元類? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? 友元類的所有成員函數(shù)都可以是另一個類的友元函數(shù), 都可以訪問另一個類中的非公有成員。
5.1 概念及特性
概念: 如果一個類定義在另一個類的內(nèi)部,這個類就叫做內(nèi)部類。注意此時這個內(nèi)部類是一個獨立的類,它不屬于外部類,更不能通過外部類的對象去調(diào)用內(nèi)部類。外部類對內(nèi)部類沒有任何優(yōu)越的訪問權(quán)限。
注意:內(nèi)部類就是外部類的右元類。注意友元類的定義,內(nèi)部類可以通過外部類的對象參數(shù)來訪問外部類中的所有成員。但是外部類不是內(nèi)部類的友元。
特性:
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;
}
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
本文標題:C++10再次理解類的成員函數(shù)-創(chuàng)新互聯(lián)
網(wǎng)頁網(wǎng)址:http://www.rwnh.cn/article44/ppehe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、網(wǎng)站維護、小程序開發(fā)、網(wǎng)站設(shè)計公司、全網(wǎng)營銷推廣、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)