欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報激活碼778899分享:【C++】類和對象(下)

Wish心愿購綜合2025-08-24560

柚子快報激活碼778899分享:【C++】類和對象(下)

http://yzkb.51969.com/

【C++】類和對象(下)

初始化列表構(gòu)造時的類型轉(zhuǎn)化static成員概念特性

友元友元函數(shù)友元類

內(nèi)部類匿名對象總結(jié)

初始化列表

在對類和對象有了基本的認(rèn)識之后,可以知道在創(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ù)賦予了成員變量新的值,但不能稱之為對對象中成員變量的初始化,構(gòu)造函數(shù)中的語句只能稱之為賦初值,而不能稱作初始化。

初始化只能初始化一次,而構(gòu)造函數(shù)體內(nèi)可以多次賦值。

初始化列表:以一個冒號開始,接著是一個以逗號分隔的數(shù)據(jù)或成員列表,每個成員變量后面跟著一個放在括號中的初始值或者表達(dá)式。

class Date

{

public:

Date(int year, int month, int day)

//對象的定義

:_year(year)

,_month(month)

,_day(day)

{}

private:

//對象的聲明

int _year;

int _month;

int _day;

};

int main(void)

{

Date d(2000,1,1);//對象的整體定義

return 0;

}

成員變量在類里面是聲明,在主函數(shù)(main)中會對成員變量進(jìn)行對象的整體定義,所有C++中規(guī)定了初始化列表,對象的成員定義的位置便是在初始化列表,在構(gòu)造函數(shù)體內(nèi)進(jìn)行的是成員變量的賦值。

【注意】 1.每一個成員變量在初始化列表中最多只能出現(xiàn)一次(初始化只能初始化一次)

成員變量可以在初始化列表不出現(xiàn),但是出現(xiàn)最多只能出現(xiàn)一次,否則就會報錯。

如果成員變量在初始化列表中不出現(xiàn),成員變量中的內(nèi)置類型不做處理,而自定義類型會調(diào)用其默認(rèn)的構(gòu)造函數(shù)。

2.類中包含以下成員,必須放在初始化列表位置進(jìn)行初始化。

引用成員變量

class B

{

public:

B(int& i)

:_i(i)

{}

private:

int& _i;

};

int main(void)

{

int i = 10;

B b1(i);

return 0;

}

當(dāng)類中存在引用成員變量時,必須在定義的時候初始化。 而在傳引用值時,需要預(yù)先在出函數(shù)中定義好一個變量,構(gòu)造函數(shù)接收參數(shù)時使用引用,如果只是傳遞一個值,在調(diào)用構(gòu)造函數(shù)時會建立一個臨時變量存儲這個值,當(dāng)構(gòu)造函數(shù)銷毀時,臨時變量也會銷毀,那么此時這個引用就會變成一種野引用。

const成員變量

class B

{

public:

B(int c)

:_c(c)

{}

private:

const int _c;

};

int main(void)

{

B bb1(10);

return 0;

}

當(dāng)類中存在const修飾成員變量時,必須在定義的時候初始化。 被const修飾的變量只有一次初始機(jī)會,此后不可以被修改,所有必須在初始化列表的定義。

自定義類型(且該類型沒有默認(rèn)的構(gòu)造函數(shù))

class A

{

public:

A(int a)

:_a(a)

{}

private:

int _a;

};

class B

{

public:

B(int aa)

:_aa(aa)

{}

private:

A _aa;

};

int main(void)

{

B bb(1);

return 0;

}

當(dāng)自定義類型沒有默認(rèn)構(gòu)造函數(shù)(全缺省、無參、編譯器自定生成),需要在初始化列表定義,由默認(rèn)構(gòu)造函數(shù),也可以在初始化列表進(jìn)行定義。

有默認(rèn)構(gòu)造函數(shù),默認(rèn)構(gòu)造函數(shù)的參數(shù)為缺省值,需要先考慮初始化列表,初始化列表可以看作是成員變量定義的地方。

【注意】 初始化只是構(gòu)造函數(shù)的一部分,構(gòu)造函數(shù)里面初始化賦值有倆種:第一種是在函數(shù)體內(nèi)賦值,另一種是初始化列表定義。

也就是說,并不是初始化列表可以滿足構(gòu)造函數(shù)的問題,在構(gòu)造函數(shù)內(nèi)部可以進(jìn)行一些其他的工作,例如內(nèi)存的開辟,內(nèi)存開辟后的判斷,多維數(shù)組的建立等等。

class Stack

{

public:

Stack(int capacity)

:_capacity(capacity)

,_size(0)

{

_a = (int*)malloc(sizeof(int) * capacity);

if (_a == nullptr)

{

perror("malloc fail");

return;

}

}

private:

int* _a;

int _capacity;

int _size;

};

3.盡量使用初始化列表初始化,因為不管你是否使用初始化列表,對于自定義類型成員變量,一定會先使用初始化列表。

4.成員變量在類中聲明次序就是其在初始化列表中的初始化順序,與其在初始化列表中的先后順序無關(guān)。

class A

{

public:

A(int a)

:_a2(a)

,_a1(_a2)

{}

private:

int _a1;

int _a2;

};

這段錯誤代碼就演示了在初始化列表中先定義_a1時,使用_a2的值賦給_a1,由于_a2還未定義,所以_a1會出現(xiàn)隨機(jī)值。

構(gòu)造時的類型轉(zhuǎn)化

class A

{

public:

A(int a)

:_a(a)

{}

private:

int _a;

};

int main(void)

{

A aa1 = 2;

return 0;

}

對對象初始化時,將一個整數(shù)類型賦值給自定義類型,這種方式被稱為隱式類型轉(zhuǎn)換,會先通過整數(shù)構(gòu)造一個自定義類型的臨時變量,臨時變量在拷貝構(gòu)造給需要構(gòu)造的對象——>這種過程直接會被編譯器有優(yōu)化為直接構(gòu)造,不通過拷貝構(gòu)造。 在同一個表達(dá)式中,連續(xù)的構(gòu)造編譯器一般會優(yōu)化。

這段代碼報錯的原因是,整數(shù)int類型在構(gòu)造一個自定義類型的臨時變量時,由于臨時變量具有常性,所以在將臨時變量拷貝給自定義類型時,臨時變量會釋放,引用會變成野引用,所以直接使用引用是不可以的。

可以使用const來使用引用,因為const引用不能被修改。

使用explicit關(guān)鍵字修飾構(gòu)造函數(shù),將會禁止構(gòu)造函數(shù)的隱式住轉(zhuǎn)化。

static成員

概念

聲明為static的類成員稱為類的靜態(tài)成員,用static修飾的成員變量稱為靜態(tài)成員變量。用static修飾的成員函數(shù)稱之為靜態(tài)成員函數(shù)。

靜態(tài)成員變量一定要在類外進(jìn)行初始化。

例如:檢查程序中有多少個對象正在使用

//使用全局變量

int _count = 0;

class A

{

public:

A(int a)

:_a(a)

{

++_count;

}

A(const A& a)

{

++_count;

}

~A()

{

--_count;

}

private:

int _a;

};

void Fun1()

{

A aa3(2);

cout << __LINE__ << ":" << _count << endl;

}

int main(void)

{

A aa1(1);

cout << __LINE__ << ":" << _count << endl;

A aa2(aa1);

cout << __LINE__ << ":" << _count << endl;

Fun1();

cout << __LINE__ << ":" << _count << endl;

return 0;

}

此代碼使用全局變量來測試,但是全局變量的劣勢是任何地方都可以將其修改。

類中除了可以定義成員變量,同時也可以定義靜態(tài)成員變量。

class A

{

public:

A(int a)

:_a(a)

{

++_count;

}

A(const A& a)

{

++_count;

}

~A()

{

--_count;

}

static int GetCount()

{

return _count;

}

private:

int _a;

static int _count;

};

int A::_count = 0;

void Fun1()

{

A aa3(2);

cout << __LINE__ << ":" << A::GetCount() << endl;

}

int main(void)

{

A aa1(1);

cout << __LINE__ << ":" << A::GetCount() << endl;

A aa2(aa1);

cout << __LINE__ << ":" << A::GetCount() << endl;

Fun1();

cout << __LINE__ << ":" << A::GetCount() << endl;

return 0;

}

對于成員變量與靜態(tài)成員變量的區(qū)別是,成員變量屬于每一個類對象,每一個對象中都會有成員變量,而靜態(tài)成員變量只屬于類,屬于類中每一個類對象共享的變量,存儲在靜態(tài)區(qū),其聲明周期是全局的。

靜態(tài)成員變量只在全局位置,類的外面定義,由于靜態(tài)成員變量在類中被封裝后變成私有,所以靜態(tài)成員函數(shù)不可以被訪問,所以可以使用類中公共的成員函數(shù)。

class A

{

public:

A(int a)

:_a(a)

{

++_count;

}

A(const A& a)

{

++_count;

}

~A()

{

--_count;

}

int GetCount()

{

return _count;

}

private:

int _a;

static int _count;

};

int A::_count = 0;

void Fun1()

{

A aa3(2);

cout << __LINE__ << ":" << aa3.GetCount() << endl;

}

int main(void)

{

A aa1(1);

cout << __LINE__ << ":" << aa1.GetCount() << endl;

A aa2(aa1);

cout << __LINE__ << ":" << aa1.GetCount() << endl;

Fun1();

cout << __LINE__ << ":" << aa1.GetCount() << endl;

return 0;

}

這種方式是無法對沒有對象的程序進(jìn)行調(diào)用函數(shù)。

所以也可以使用靜態(tài)成員函數(shù),靜態(tài)成員函數(shù)沒有this指針,指定類域或者訪問限定符就可以訪問靜態(tài)成員函數(shù),靜態(tài)成員函數(shù)中不能使用非靜態(tài)成員變量,因為沒有this指針。

【注意】由于靜態(tài)成員變量無法進(jìn)入構(gòu)造,所以無法通過初始化列表定義,所以在聲明靜態(tài)成員變量時,無法給缺省值。

鏈接:使用static計算1+2+3……+n

class Sum

{

public:

Sum()

{

_sum += _num;

++_num;

}

static int GetSum()

{

return _sum;

}

private:

static int _num;

static int _sum;

};

int Sum::_num = 1;

int Sum::_sum = 0;

class Solution {

public:

int Sum_Solution(int n)

{

Sum arr[n];

return Sum::GetSum();

}

};

設(shè)計一個類只能在棧上創(chuàng)建對象

class A

{

public:

static A GetStackObj(int a)

{

A a1(a);

return a1;

}

private:

A(int a1)

:_a1(a1)

{}

int _a1;

};

int main(void)

{

A a1 = A::GetStackObj();

return 0;

}

特性

1.靜態(tài)成員為所有類對象所共享,不屬于某個具體的對象,存放在靜態(tài)區(qū) 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,privated的影響 6.非靜態(tài)成員函數(shù)可以調(diào)用靜態(tài)成員函數(shù),原因是靜態(tài)成員函數(shù)沒有this指針,不構(gòu)成影響 7.靜態(tài)成員函數(shù)不能調(diào)用非靜態(tài)成員函數(shù),是因為非靜態(tài)成員函數(shù)調(diào)用需要this指針,而靜態(tài)成員函數(shù)沒有this指針

友元

友元提供了一種突破封裝的方式,有時可以利用友元提供方便,但使用友元會增加耦合度(關(guān)聯(lián)度更加緊密),可能會破壞封裝。 友元使用關(guān)鍵字friend 友元可以分為:友元函數(shù)與友元類。

友元函數(shù)

友元函數(shù)可以直接訪問類的私有成員,它是定義在類外部的普通函數(shù),不屬于任何類,但需要在類的內(nèi)部聲明,聲明時需要加friend關(guān)鍵字。

以流插入舉例:

class Date

{

friend ostream& operator<<(ostream& out, 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& out, Date& d)

{

out << d._year << "/" << d._month << "/" << d._day;

return out;

}

觀察這段代碼,無法將operator<<放在類中成為重載成員函數(shù),是因為cout的輸出流對象和隱含的this指針在搶占第一個參數(shù)的位置,this指針默認(rèn)是第一個參數(shù),也就是左操作數(shù)。

d << cout;

但是實際使用中cout需要是第一個形參對象,才能正常使用,可以將operator重載成全局函數(shù),但是此時又會導(dǎo)致類外沒辦法訪問成員,此時就需要友元來解決。

【注意】 1.友元函數(shù)可以訪問類的私有和保護(hù)成員,但是不是類的成員函數(shù) 2.友元函數(shù)不能使用const修飾 3.友元函數(shù)可以哎類定義的任何地方聲明,不受類訪問限定符限制 4.一個函數(shù)可以是多個類的友元函數(shù) 5.友元函數(shù)的調(diào)用與普通的調(diào)用原理相同

友元類

class Date

{

friend class Time;

public:

Date(int year = 2000, int month = 1, int day = 1)

:_year(year)

, _month(month)

, _day(day)

{}

private:

int _year;

int _month;

int _day;

};

class Time

{

public:

Time(int hour, int minute, int second)

:_hour(hour)

,_minute(minute)

,_second(second)

{}

void Print()

{

cout << _d._year << " " << _d._month << " " << _d._day << " "

<< _hour << " " << _minute << " " << _second;

}

private:

int _hour;

int _minute;

int _second;

Date _d;

};

int main(void)

{

Time T1(2, 23, 15);

T1.Print();

return 0;

}

友元類的所有成員函數(shù)都可以是另一個類的友元函數(shù),都可以訪問另一個類中的非公有成員。

友元函數(shù)是單向的,不具有交換性。友元關(guān)系不能傳遞。 例如:如果C是B的友元,B是A的友元,則不能說明C是A的友元。友元關(guān)系不能繼承。

內(nèi)部類

概念·:如果一個類定義在另一個類的內(nèi)部,這個內(nèi)部類就叫做內(nèi)部類。內(nèi)部類是一個獨立的類,它不屬于外部類,更不能通過外部類的對象去訪問內(nèi)部類的成員。外部類對內(nèi)部類沒有任何優(yōu)越的訪問權(quán)限。

【特性】 1.內(nèi)部類可以定義在外部類的public、protected、private都是可以的,其效果不同。 2.注意內(nèi)部類可以直接訪問外部類中的static成員,不需要外部類的對象或者類名 3.sizeof(外部類)==外部類,和內(nèi)部類沒有任何關(guān)系。 4.sizeof(類)時,里面的靜態(tài)變量不計算,是因為靜態(tài)變量沒有存儲在對象里面。 5.內(nèi)部類天生是外部類的友元。

class A

{

public:

class B

{

public:

B()

:_b(2)

{}

void Print(const A& a)

{

cout << a._a << _b << endl;

}

private:

int _b;

};

A()

:_a(1)

{}

private:

int _a;

};

int main()

{

A a;

A::B b;

b.Print(a);

return 0;

}

【注意】 內(nèi)部類就是外部類的友元類,同友元類一樣,內(nèi)部類可以通過外部類的對象參數(shù)來訪問外部類中的所有成員,但外部類不是內(nèi)部類的友元。

匿名對象

有名對象

A aa1(1);

匿名對象

A(2);

有名對象調(diào)用調(diào)用函數(shù)

Date d1;

d1.Print();

匿名函數(shù)調(diào)用對象

Date().Print();

有名對象的生命周期在當(dāng)前函數(shù)局部域,匿名對象的生命周期在當(dāng)前行。

匿名對象與有名對象的區(qū)別僅僅是匿名無名,而有名有名。

匿名對象與臨時對象相似,具有常性。

//錯誤代碼

A& a1 = A(1);

//正確代碼

const A& a2 = A(1);

const引用延長了匿名對象的生命周期,生命周期在當(dāng)前函數(shù)局部域。

同時,同一行一個表達(dá)式中連續(xù)的構(gòu)造+拷貝構(gòu)造會進(jìn)行優(yōu)化。

總結(jié)

在類和對象階段,需要體會到,類是對某一類實體(對象)來進(jìn)行描述的,描述該對象具有哪些屬性,哪些方法,描述完成后就形成了一種新的自定義類型,才有該自定義類型就可以實例化具體的對象。

柚子快報激活碼778899分享:【C++】類和對象(下)

http://yzkb.51969.com/

好文推薦

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19024370.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄