欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++類和對(duì)象補(bǔ)充

 更新時(shí)間:2021年10月21日 15:55:29   作者:藍(lán)樂(lè)  
類是創(chuàng)建對(duì)象的模板,一個(gè)類可以創(chuàng)建多個(gè)對(duì)象,每個(gè)對(duì)象都是類類型的一個(gè)變量;創(chuàng)建對(duì)象的過(guò)程也叫類的實(shí)例化。每個(gè)對(duì)象都是類的一個(gè)具體實(shí)例(Instance),擁有類的成員變量和成員函數(shù)

一. 再看構(gòu)造函數(shù)

我們之前已經(jīng)了解了構(gòu)造函數(shù)的基本內(nèi)容,那么這里我們將深入認(rèn)識(shí)構(gòu)造函數(shù)。

1.函數(shù)體內(nèi)賦初值

class Date
{
public:
 Date(int year, int month, int day)
 {
 _year = year;
 _month = month;
 _day = day;
 //可以進(jìn)行多次賦值,但一般不這么做
 _year = 1;
 }
private:
 int _year;
 int _month;
 int _day;
};

首先,對(duì)于構(gòu)造函數(shù)體內(nèi)的賦值我們不能稱之為初始化。首先我們要理解:初始化只能初始化一次,而構(gòu)造函數(shù)體內(nèi)可以多次賦值。那么對(duì)象成員變量的初始化是在什么時(shí)候進(jìn)行的呢?這就要接下來(lái)要介紹的初始化列表要做的事了。

2.初始化列表

初始化列表是以一個(gè)冒號(hào)開(kāi)始,接著是一個(gè)以逗號(hào)分隔的數(shù)據(jù)成員列表,每個(gè)"成員變量"后面跟一個(gè)放在括號(hào)中的初始值或表達(dá)式。其形式如下:

class Date
{
public:
	Date(int year = 0, int month = 1, int day = 1)
		:_year(year)
		,_month(month)
	{
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

幾點(diǎn)注意

1.每個(gè)成員變量在初始化列表中只能出現(xiàn)一次(初始化只能初始化一次)

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

(1)const成員變量:由于const變量初始化之后就不能更改,因此需在初始化列表進(jìn)行初始化。

(2)引用成員變量:引用成員變量只能作為一個(gè)變量的引用,一旦初始化,就不能再作為其他變量的引用,因此引用變量也只能再初始化列表初始化。

(3)自定義類型成員變量(沒(méi)有默認(rèn)構(gòu)造函數(shù)情況下):由于沒(méi)有默認(rèn)構(gòu)造函數(shù)時(shí),自定義類型變量是不能初始化的,此時(shí)程序也無(wú)法編譯,因此沒(méi)有默認(rèn)構(gòu)造函數(shù)的自定義類型成員變量必須在初始化列表進(jìn)行初始化。

class B
{
public:
	B(int i)
		:_i(i)
	{
	}
private:
	int _i;
};
class A
{
public:
	A(int a, int& b, int bb)
		:_a(a)
		,_b(b)
		,_bb(bb)
	{
	}
private:
	const int _a;//const成員變量
	int& _b;//引用成員變量
	B _bb;//自定義成員變量
};

3.盡量使用初始化列表初始化,因?yàn)椴还苣闶欠袷褂贸跏蓟斜恚瑢?duì)于自定義類型成員變量,一定會(huì)先使用初始化列表初始化。比如下面代碼的執(zhí)行結(jié)果:

class B
{
public:
	B()
	{
		cout << "B()" << endl;
	}
private:
	int _i;
};
class A
{
public:
	A(int a, int& b)
		:_a(a)
		,_b(b)
	{
	}
private:
	const int _a;//const成員變量
	int& _b;//引用成員變量
	B _bb;//自定義成員變量
};
int main()
{
	int n = 0;
	A a1(0, n);
	return 0;
}

在這里插入圖片描述

可以看到,初始化列表中并沒(méi)有對(duì)自定義變量_bb初始化,但程序仍然調(diào)用了自定義類型的默認(rèn)構(gòu)造函數(shù)。

4. 成員變量在類中聲明次序就是其在初始化列表中的初始化順序,與其在初始化列表中的先后次序無(wú)關(guān),先想想下面的代碼運(yùn)行結(jié)果是什么:

class 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();
	return 0;
}

在這里插入圖片描述

可以看到的是,_a1為1,而_a2為隨機(jī)值,這是因?yàn)樵诔蓡T列表的聲明中,_a2先被聲明,_a1后被聲明,因此初始化列表中的順序是先_a2,后_a1。而一開(kāi)始_a1為隨機(jī)值,因此最終_a2為隨機(jī)值。

3.explicit關(guān)鍵字

我們知道,對(duì)于構(gòu)造函數(shù),不僅可以構(gòu)造和初始化對(duì)象,對(duì)于單個(gè)參數(shù)的構(gòu)造函數(shù),還具有類型轉(zhuǎn)換的作用。

比如Date類:

class Date
{
public:
	Date(int year)
		:_year(year)
	{}
	explicit Date(int year)
		:_year(year)
	{}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2020);
	// 用一個(gè)整形變量給日期類型對(duì)象賦值
	// 實(shí)際編譯器背后會(huì)用2019構(gòu)造一個(gè)無(wú)名對(duì)象,最后用無(wú)名對(duì)象給d1對(duì)象進(jìn)行賦值
	Date d2 = 2021;//explict禁止隱式類型轉(zhuǎn)換,因此該句代碼運(yùn)行錯(cuò)誤
}

但是Date d2 = 2021;這樣的代碼可讀性不是很好,因此可以使用explicit關(guān)鍵字將這種隱式類型轉(zhuǎn)換禁止。

二.static成員

C語(yǔ)言中我們就接觸了static關(guān)鍵字,那么這個(gè)關(guān)鍵字修飾成員會(huì)怎么樣呢?

1.概念

聲明為static的類成員稱為類的靜態(tài)成員,用static修飾的成員變量,稱之為靜態(tài)成員變量;用static修飾的成員函數(shù),稱之為靜態(tài)成員函數(shù)。像上面初始化列表中說(shuō)的,靜態(tài)的成員變量一定要在類外進(jìn)行初始化。

2.特性

靜態(tài)成員存儲(chǔ)在靜態(tài)區(qū),為所有類對(duì)象所共享,不屬于某個(gè)具體的實(shí)例

靜態(tài)成員變量必須在類外定義,定義時(shí)不添加static關(guān)鍵字

類靜態(tài)成員即可用類名::靜態(tài)成員或者對(duì)象.靜態(tài)成員來(lái)訪問(wèn)

靜態(tài)成員函數(shù)沒(méi)有隱藏的this指針,不能訪問(wèn)任何非靜態(tài)成員;相對(duì)的,非靜態(tài)成員函數(shù)可以通過(guò)this指針訪問(wèn)靜態(tài)成員變量。

靜態(tài)成員和類的普通成員一樣,也有public、protected、private 3種訪問(wèn)級(jí)別,也可以具有返回值

接下來(lái)我們來(lái)看看一道題:

求1+2+3+…+n

題目描述:求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等關(guān)鍵字及條件判斷語(yǔ)句(A?B:C)。
這道題我們可以利用構(gòu)造函數(shù),由于每次實(shí)例化對(duì)象,都會(huì)調(diào)用其構(gòu)造函數(shù),因此我們可以實(shí)例化n個(gè)對(duì)象,每次初始化時(shí)計(jì)算求和即可;

class Sum
{
public:
    //調(diào)用構(gòu)造函數(shù)
    Sum()
    {
        _sum += _i;
        ++_i;
    }
    //static修飾的成員函數(shù),沒(méi)有隱含的this指針,只能訪問(wèn)靜態(tài)成員變量
    static int GetSum()
    {
        return _sum;
    }
private:
	//static修飾的成員變量為所有定義出來(lái)的類對(duì)象共有
    static int _i;
    static int _sum;
};
//靜態(tài)成員變量的定義
int Sum::_i = 1;
int Sum::_sum = 0;
class Solution {
public:
    int Sum_Solution(int n) {
        Sum* p = new Sum[n];
        return Sum::GetSum();
    }
};

【注意】sizeof(類名)不計(jì)算靜態(tài)成員變量的大小。比如上述代碼中的sizeof(Sum)為1,是一個(gè)空類。

三.友元

友元分為友元函數(shù)和友元類,其提供了一種突破封裝的方式,有時(shí)提供了便利。但是友元會(huì)增加耦合度,破壞了封裝,所以友元不宜多用。

1.友元函數(shù)

首先如果我們要重載<<(流插入)運(yùn)算符,我們會(huì)發(fā)現(xiàn)將其定義成類成員函數(shù)將無(wú)法實(shí)現(xiàn),這是因?yàn)轭惓蓡T函數(shù)的第一個(gè)參數(shù)為this指針,那么我們只能將這個(gè)函數(shù)定義在類外,但是這樣的話函數(shù)又不能訪問(wèn)類中的成員變量,那么這個(gè)時(shí)候要么在成員函數(shù)中實(shí)現(xiàn)訪問(wèn)的方法,要么就使用友元函數(shù),使其可以訪問(wèn)類中成員。即:

class Date
{
	//用關(guān)鍵字friend在類中聲明函數(shù)為Date的友元函數(shù)
	friend ostream& operator<<(ostream& out, const 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, const Date& d)
{
	out << d._year << "/" << d._month << "/" << d._day;
	return out;
}
int main()
{
	Date d1(2021, 10, 20);
	cout << d1 << endl;
}

同理,cin也可以如此定義。

【說(shuō)明】

1.友元函數(shù)可訪問(wèn)類的私有和保護(hù)成員,但不是類的成員函數(shù)

2.友元函數(shù)不能用const修飾

3.友元函數(shù)可以在類定義的任何地方聲明,不受類訪問(wèn)限定符限制

4.一個(gè)函數(shù)可以是多個(gè)類的友元函數(shù)

5.友元函數(shù)的調(diào)用與普通函數(shù)的調(diào)用和原理相同

2.友元類

和友元函數(shù)相似,友元類可以訪問(wèn)另一個(gè)類的私有成員。比如下面代碼中,B作為A的友元類,可以訪問(wèn)A中的_a和_i。

class A
{
	//聲明B為A的友元類,則在B中可以訪問(wèn)A中的成員
	friend class B;
public:
	A(int a)
		:_a(a)
	{
	}
private:
	int _a;
	static int _i;
};
class B
{
public:
	B(int b)
		:_b(b)
	{}
	static int Count()
	{
		A::_i++;
		return A::_i;
	}
private:
	int _b;
};
int A::_i = 0;
int main()
{
	A a1(1);
	B b1(1);
	cout << b1.Count() << endl;
	cout << b1.Count() << endl;
	return 0;
}

需要注意,友元關(guān)系是單向的,不具有交換性,比如上述代碼中A不能訪問(wèn)B中的成員;友元關(guān)系不能傳遞,即B是A的友元,C是B的友元,但C不是A的友元,C就不能訪問(wèn)A中的私有成員。

四.內(nèi)部類

顧名思義,定義在另一個(gè)類中的類就是內(nèi)部類。注意此時(shí)這個(gè)內(nèi)部類是一個(gè)獨(dú)立的類,它不屬于外部類,更不能通過(guò)外部類的對(duì)象去調(diào)用內(nèi)部類。外部類對(duì)內(nèi)部類沒(méi)有任何優(yōu)越的訪問(wèn)權(quán)限。

內(nèi)部類就是外部類的友元類。注意友元類的定義,內(nèi)部類可以通過(guò)外部類的對(duì)象參數(shù)來(lái)訪問(wèn)外部類中的所有成員。但是外部類不是內(nèi)部類的友元。

class A
{
public:
	class B//內(nèi)部類,是A的友元類
	{
	public:
	//B可以直接訪問(wèn)A的成員
		void Print(const A& a)
		{
			cout << a._a << endl;
			cout << _i << endl;
		}
	};
	A(int a)
		:_a(a)
	{}
private:
	int _a;
	static int _i;
};
int main()
{
	A::B b1;//注意B的調(diào)用方式
	A a1(1);
	b1.Print(a1);
	//但A的對(duì)象不能去訪問(wèn)B中的成員
	a1.b1;//error
}

特性:

1.內(nèi)部類可以定義在外部類的public、protected、private都是可以的。

2.注意內(nèi)部類可以直接訪問(wèn)外部類中的static、枚舉成員,不需要外部類的對(duì)象/類名。

3.sizeof(外部類)=外部類,和內(nèi)部類沒(méi)有任何關(guān)系。比如上面的sizeof(A)為4。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • VS2013安裝配置和使用Boost庫(kù)教程

    VS2013安裝配置和使用Boost庫(kù)教程

    這篇文章主要為大家詳細(xì)介紹了VS2013安裝配置和使用Boost庫(kù)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • C++ OpenCV實(shí)現(xiàn)灰度圖蒙版GrayMask的示例代碼

    C++ OpenCV實(shí)現(xiàn)灰度圖蒙版GrayMask的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C++和OpenCV實(shí)現(xiàn)灰度圖蒙版GrayMask,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定參考價(jià)值,需要的可以參考一下
    2022-05-05
  • C語(yǔ)言實(shí)現(xiàn)餐廳管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)餐廳管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)餐廳管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++中引用(&)的用法與應(yīng)用實(shí)例分析

    C++中引用(&)的用法與應(yīng)用實(shí)例分析

    引用是C++引入的新語(yǔ)言特性,是C++常用的一個(gè)重要內(nèi)容之一,正確、靈活地使用引用,可以使程序簡(jiǎn)潔、高效。故在本篇中我將對(duì)引用進(jìn)行詳細(xì)討論,希望對(duì)大家更好地理解和使用引用起到拋磚引玉的作用
    2013-09-09
  • C++ 中友元函數(shù)與友元類詳解

    C++ 中友元函數(shù)與友元類詳解

    這篇文章主要介紹了C++ 中友元函數(shù)與友元類詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • C語(yǔ)言指針超詳細(xì)講解下篇

    C語(yǔ)言指針超詳細(xì)講解下篇

    指針提供了對(duì)地址操作的一種方法,因此,使用指針可使得?C?語(yǔ)言能夠更高效地實(shí)現(xiàn)對(duì)計(jì)算機(jī)底層硬件的操作。另外,通過(guò)指針可以更便捷地操作數(shù)組。在一定意義上可以說(shuō),指針是?C?語(yǔ)言的精髓
    2022-04-04
  • C++的get()函數(shù)與getline()函數(shù)使用詳解

    C++的get()函數(shù)與getline()函數(shù)使用詳解

    這篇文章主要介紹了C++的get()函數(shù)與getline()函數(shù)使用詳解,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C++排序算法之插入排序解析

    C++排序算法之插入排序解析

    這篇文章主要介紹了C++排序算法之插入排序解析,將數(shù)組分為有序表和無(wú)序表,每次從有序表中取出一個(gè)元素,插入到有序表的適當(dāng)位置,每遍歷一次,有序表中元素增加一個(gè),無(wú)序表中元素個(gè)數(shù)減少一個(gè),重復(fù)n-1次,完成排序,需要的朋友可以參考下
    2023-10-10
  • 基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的掃雷游戲

    基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的掃雷游戲

    windows自帶的游戲《掃雷》是陪伴了無(wú)數(shù)人的經(jīng)典游戲,本文將利用C語(yǔ)言實(shí)現(xiàn)這一經(jīng)典的游戲,文中的示例代碼講解詳細(xì),感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • TensorFlow源代碼構(gòu)建流程記錄解析

    TensorFlow源代碼構(gòu)建流程記錄解析

    這篇文章主要為大家介紹了TensorFlow源代碼構(gòu)建流程記錄解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01

最新評(píng)論