国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載

這篇具有很好參考價(jià)值的文章主要介紹了C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法

??個(gè)人主頁:?? :???初階牛???
??推薦專欄1: ??????C語言初階
??推薦專欄2: ??????C語言進(jìn)階
??個(gè)人信條: ??知行合一
??本篇簡介:>:講解C++中有關(guān)類和對(duì)象的介紹,本篇是中篇的第結(jié)尾篇文章,講解拷貝構(gòu)造,運(yùn)算符重載以及取地址重載符.
金句分享:
?別在最好的年紀(jì),辜負(fù)了最好的自己.?

一、“拷貝構(gòu)造函數(shù)”

拷貝構(gòu)造函數(shù)

只有單個(gè)形參,該形參是對(duì)本類類型對(duì)象的引用(一般常用const修飾),在用已存在的類類型對(duì)象創(chuàng)建新對(duì)象時(shí)由編譯器自動(dòng)調(diào)用。

2.1 自動(dòng)生成的"拷貝構(gòu)造函數(shù)"

假設(shè)哦我們需要?jiǎng)?chuàng)建兩個(gè)一模一樣的對(duì)象AB.
C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法
那我們可以先創(chuàng)建一個(gè)對(duì)象A,再通過將A作為參數(shù),傳給B進(jìn)行初始化,
即一個(gè)自定義類型實(shí)例化出的對(duì)象(B)用另一個(gè)該類型實(shí)例化出的對(duì)象(A)進(jìn)行初始化.

class Date
{
public:

	Date(int year = 2020, int month = 1, int day = 1)//全缺省構(gòu)造函數(shù)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};


int main()
{
	Date A(2023, 7, 20);
	A.Print();
	printf("\n");
	Date B(A);//會(huì)調(diào)用系統(tǒng)生成的拷貝構(gòu)造
	B.Print();
	return 0;
}

運(yùn)行結(jié)果:

2023-7-20

2023-7-20

其實(shí)拷貝構(gòu)造函數(shù)就是構(gòu)造函數(shù)的一種重載形式,他也是六大天選之子之一,沒有顯式定義時(shí),編譯器也會(huì)自動(dòng)生成,但是只會(huì)完成"淺拷貝"(下面講)…

2.2 自定義"拷貝構(gòu)造函數(shù)"

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Date
{
public:

	Date(int year = 2020, int month = 1, int day = 1)//全缺省構(gòu)造函數(shù)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)//拷貝構(gòu)造函數(shù)
	{
		cout << "拷貝構(gòu)造" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2023, 7, 20);
	d1.Print();
	printf("\n");
	Date d2(d1);
	d2.Print();
	return 0;
}

我們發(fā)現(xiàn)Date(const Date& d)這里使用了引用傳參,如果直接傳參會(huì)怎樣呢?
C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法
為什么會(huì)報(bào)錯(cuò)呢?

void test(int a)
{

}

void test(Date d1)
{

}

int main()
{
	Date d1(2023, 7, 20);
	test(2);
	test(d1);
	return 0;
}

這段代碼會(huì)調(diào)用Date 類的拷貝構(gòu)造.
C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法
對(duì)于自定義類型作為參數(shù)時(shí),必須調(diào)用該類型的拷貝構(gòu)造函數(shù).
所以可以回答上面的問題了.

C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法
所以拷貝構(gòu)造函數(shù)傳參時(shí)采用引用傳參,這樣就避免了傳參時(shí)調(diào)用拷貝構(gòu)造.

2.3 深淺拷貝?

前面在介紹編譯器自動(dòng)生成的"拷貝構(gòu)造函數(shù)"時(shí),提到了淺拷貝,那什么是淺拷貝呢?

淺拷貝:按內(nèi)存存儲(chǔ)按字節(jié)序完成拷貝,這種拷貝叫做淺拷貝,或者值拷貝
C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法

深拷貝:
C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法

示例:
棧類中沒有顯式定義拷貝構(gòu)造函數(shù),編譯器自動(dòng)生成的拷貝構(gòu)造是淺拷貝帶來的問題.

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

typedef int DataType;
class Stack
{
public:
	Stack(int capacity=5)//全缺省構(gòu)造函數(shù)
	{
		cout << "Stack" << endl;
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		if (NULL == _array)
		{
			perror("malloc申請(qǐng)空間失敗!!!");
			return;
		}
		_capacity = capacity;
		_size = 0;
	}
	void Push(DataType data)//壓棧操作
	{
		CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	~Stack()//析構(gòu)函數(shù)
	{
		cout << "~Stack"<< endl;
		if (_array)
		{
			free(_array);
			_array = NULL;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	void CheckCapacity()
	{
		if (_size == _capacity)
		{
			int newcapacity = _capacity * 2;
			DataType* temp = (DataType*)realloc(_array, newcapacity *
				sizeof(DataType));
			if (temp == NULL)
			{
				perror("realloc申請(qǐng)空間失敗!!!");
				return;
			}
			_array = temp;
			_capacity = newcapacity;
		}
	}
private:
	DataType* _array;
	int _capacity;
	int _size;
};
int main()
{
	Stack s1;
	s1.Push(1);
	s1.Push(2);
	s1.Push(3);
	s1.Push(4);
	Stack s2(s1);//這條語句會(huì)報(bào)錯(cuò).
	return 0;
}

運(yùn)行結(jié)果:
C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法
原因:
因?yàn)榫幾g器默認(rèn)生成的拷貝構(gòu)造是淺拷貝,這里兩個(gè)對(duì)象的_array也就指向了同一塊內(nèi)存空間,但是兩個(gè)對(duì)象的聲生命周期結(jié)束時(shí),會(huì)調(diào)用各自的析構(gòu)函數(shù),這也就導(dǎo)致對(duì)同一塊空間進(jìn)行了釋放操作.
解決方法:
顯示定義一個(gè)拷貝構(gòu)造函數(shù).

	Stack(const Stack& S)//深拷貝
	{
		_array = (int*)malloc(sizeof(int) * S._capacity);
		if (NULL == _array)
		{
			perror("malloc申請(qǐng)空間失敗!!!");
			return;
		}
		memcpy(S._array,_array,sizeof(int)*S._size);
		_capacity = S._capacity;
		_size = S._size;
	}

總結(jié):

拷貝構(gòu)造使用場景:

  • 使用已存在對(duì)象創(chuàng)建新對(duì)象
  • 函數(shù)參數(shù)類型為類類型對(duì)象
  • 函數(shù)返回值類型為類類型對(duì)象
  1. 拷貝構(gòu)造函數(shù)是構(gòu)造函數(shù)的一個(gè)重載形式。
  2. 拷貝構(gòu)造函數(shù)的參數(shù)只有一個(gè)且必須是類類型對(duì)象的引用,使用傳值方式編譯器直接報(bào)錯(cuò),因?yàn)闀?huì)引發(fā)無窮遞歸調(diào)用。
  3. 當(dāng)一個(gè)對(duì)象作為參數(shù)傳遞給函數(shù)時(shí),拷貝構(gòu)造函數(shù)會(huì)被調(diào)用來創(chuàng)建一個(gè)新的對(duì)象,該新對(duì)象與傳遞的對(duì)象具有相同的屬性和屬性值,但是它們在內(nèi)存中是獨(dú)立的。
  4. 若未顯式定義,編譯器會(huì)生成默認(rèn)的拷貝構(gòu)造函數(shù)。 默認(rèn)的拷貝構(gòu)造函數(shù)對(duì)象按內(nèi)存存儲(chǔ)按字節(jié)序完成拷貝,這種拷貝叫做淺拷貝,或者值拷貝.

二、賦值運(yùn)算符重載(“=”)

2.1 運(yùn)算符重載的介紹

class Date//日期類
{
public:
	Date(int year = 2023, int month = 10, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
void test1()
{
	Date d1(2023, 7, 28);
	Date d2;
	if (d2 == d1)
	{
		cout << "d1=d2";
	}
	if (d1 < d2)
	{
		cout << "d1<d2";
	}
}

C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法

自定義類型是無法像內(nèi)置類型一樣比較大小和使用一些常規(guī)運(yùn)算符的.
為什么呢?
C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法
因?yàn)?mark>自定義類型是用戶自己定義的,編譯器不知道該如何進(jìn)行比較.那編譯器太笨了吧,日期按 年-月-日依次比較不就行了?
個(gè)人理解:

  1. 格局打開,如果是別的類呢?比如:person是按名字還是按職位,還是按什么?你不告訴編譯器如何比較,編譯器也很無奈,不敢瞎搞的.
  2. 編譯器咋知道你year是年,要是牛牛用nian來命名,他也能識(shí)別出來是年嗎?

綜上,自定義類型如何進(jìn)行運(yùn)算比較,只有用戶自己知道,所以用戶需要自己來設(shè)計(jì)規(guī)則.

C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法
C++為了增強(qiáng)代碼的可讀性引入了運(yùn)算符重載,運(yùn)算符重載是具有特殊函數(shù)名的函數(shù),也具有其返回值類型.

函數(shù)名:關(guān)鍵字operator+需要重載的運(yùn)算符符號(hào)。
operator+ 需要重載的運(yùn)算符

注意事項(xiàng):

  • 不能通過連接其他符號(hào)來創(chuàng)建新的操作符:
    示例:operator@

  • 重載操作符必須有一個(gè)類類型參數(shù)
    運(yùn)算符重載是通過類的成員函數(shù)或全局函數(shù)來實(shí)現(xiàn)的,而這些函數(shù)必須具有特定的參數(shù)列表。
    對(duì)于成員函數(shù)的重載操作符,至少需要一個(gè)類類型參數(shù),它表示操作符的左操作數(shù)。例如,對(duì)于二元操作符(如 +、-、* 等),成員函數(shù)的參數(shù)列表通常還包括一個(gè)非常量引用或常量引用,表示操作符的右操作數(shù)。

  • 用于內(nèi)置類型的運(yùn)算符,其含義不能改變:
    例如:內(nèi)置的整型*不要實(shí)現(xiàn)為了/,害人是不對(duì)的.

  • 作為類成員函數(shù)重載時(shí),其形參看起來比操作數(shù)數(shù)目少1一個(gè),因?yàn)槌蓡T函數(shù)的第一個(gè)參數(shù)為隱藏的this .

  • 注意以下5個(gè)運(yùn)算符不能重載?!?code>.*” (點(diǎn)星) 、" :: " sizeof ? : .

在C++中,有一些操作符是不能被重載的,包括以下幾種情況:

  1. ::(作用域解析操作符):作用域解析操作符用于指定命名空間、類或結(jié)構(gòu)的作用域,并訪問其成員。它不能被重載,因?yàn)樗暮x在語言中已經(jīng)固定不可更改。

  2. .*(指針到成員操作符)和 ->*(指向成員指針的操作符):這些操作符用于訪問類的成員指針。它們存儲(chǔ)了一個(gè)指向類成員的指針,并用于在運(yùn)行時(shí)訪問該成員。它們也不能被重載。

  3. sizeof(大小操作符):sizeof操作符用于獲取一個(gè)對(duì)象或類型的大?。ㄒ宰止?jié)為單位)。它是一個(gè)編譯時(shí)的操作符,不能在運(yùn)行時(shí)被重載。因?yàn)樵诰幾g時(shí)就已經(jīng)確定了對(duì)象或類型的大小。

  4. ?:(條件操作符,即三目運(yùn)算符):條件操作符是一個(gè)三元操作符,用于根據(jù)條件選擇不同的表達(dá)式。它不能被重載,因?yàn)樗恼Z法和含義已經(jīng)在語言中定義好了。

  5. .C++中,點(diǎn)操作符(“.”)是用來訪問對(duì)象的成員的,而它本身是不能被重載的。點(diǎn)操作符的行為在語言中是固定的,無法通過重載來改變。

2.2 賦值運(yùn)算符重載:

(1)編譯器自動(dòng)生成的 “賦值運(yùn)算符重載”

class Date//日期類
{
public:
	Date(int year = 2023, int month = 10, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};


void test1()
{
	Date d1(2023, 7, 28);
	Date d2;
	d1.print();
	d2.print();
	cout << endl;

	d2 = d1;

	d1.print();
	d2.print();

}
int main()
{
	test1();
	return 0;
}

C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法

賦值運(yùn)算符只能重載成類的成員函數(shù)不能重載成全局函數(shù):
原因:

賦值運(yùn)算符如果不顯式實(shí)現(xiàn)(自己定義),編譯器會(huì)生成一個(gè)默認(rèn)的。此時(shí)用戶再在類外自己實(shí)現(xiàn)一個(gè)全局的賦值運(yùn)算符重載,就和編譯器在類中生成的默認(rèn)賦值運(yùn)算符重載沖突了,故賦值運(yùn)算符重載只能是類的成員函數(shù)。
C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法

那編譯器會(huì)生成一個(gè)默認(rèn)賦值運(yùn)算符重載會(huì)做什么事情呢?

以值的方式逐字節(jié)拷貝。注意:內(nèi)置類型成員變量是直接賦值的,而自定義類型成員變量需要調(diào)用對(duì)應(yīng)類的賦值運(yùn)算符重載完成賦值。

當(dāng)然對(duì)于日期類這種只需要淺拷貝的類來說,編譯器默認(rèn)生成就已經(jīng)足夠了,但是像stack類,同樣引發(fā)深淺拷貝的問題.

三、最后的兩個(gè)天選之子

哈哈哈,期待到最后的兩個(gè)默認(rèn)成員函數(shù)其實(shí)沒什么要講解的.

  1. 取地址操作符重載operator&()
  2. const取地址操作符重載operator&()const
    這兩個(gè)默認(rèn)成員函數(shù)一般不用重新定義 ,編譯器默認(rèn)會(huì)生成。
class Date
{ 
public :

 Date* operator&()
 {
 	return this ;
 }
 
 const Date* operator&()const
 {
 	return this ;
 }
private :
 int _year ; // 年
 int _month ; // 月
 int _day ; // 日
};

這兩個(gè)運(yùn)算符一般不需要重載,使用編譯器生成的默認(rèn)取地址的重載即可除非你想搞點(diǎn)特殊的,返回一個(gè)特定的特殊地址.

本篇內(nèi)容到此講解完了,后續(xù)介紹日期類的具體實(shí)現(xiàn),方便大家更好的理解類和對(duì)象的知識(shí),實(shí)戰(zhàn)才能鍛煉水平哦.
C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載,C++,c++,開發(fā)語言,c語言,算法文章來源地址http://www.zghlxwxcb.cn/news/detail-635623.html

到了這里,關(guān)于C++的六大“天選之子“拷貝構(gòu)造與與運(yùn)算符重載的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包