亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++深入探究類與對象之友元與運算符重載

 更新時間:2022年04月24日 15:07:17   作者:緣友一世  
友元就是讓一個函數(shù)或者類,訪問另一個類中的私有成員;打個比方,這相當(dāng)于是說:朋友是值得信任的,所以可以對他們公開一些自己的隱私,運算符重載的實質(zhì)就是函數(shù)重載或函數(shù)多態(tài),運算符重載是一種形式的C++多態(tài),目的在于讓人能夠用同名的函數(shù)來完成不同的基本操作

友元

生活中你的家有客廳(Public),有你的臥室(Private),客廳所有來的客人都可以進去,但是你的臥室是私有的,也就是說只有你能進去,但是呢,你也可以允許你的好閨蜜好基友進去。

在程序里,有些私有屬性也想讓類外特殊的一些函數(shù)或者類進行訪問,就需要用到友元的技術(shù)。

友元的目的就是讓一個函數(shù)或者類訪問另一個類中私有成員。

友元的關(guān)鍵字為: friend

友元的三種實現(xiàn):

  • 全局函數(shù)做友元
  • 類做友元
  • 成員函數(shù)做友元

1 全局函數(shù)做友元

class Building
{
	//告訴編譯器 goodGay全局函數(shù) 是 Building類的好朋友,可以訪問類中的私有內(nèi)容
	friend void goodGay(Building * building);
public:
	Building()
	{
		this->m_SittingRoom = "客廳";
		this->m_BedRoom = "臥室";
	}
public:
	string m_SittingRoom; //客廳
private:
	string m_BedRoom; //臥室
};
void goodGay(Building * building)
{
	cout << "好基友正在訪問: " << building->m_SittingRoom << endl;
	cout << "好基友正在訪問: " << building->m_BedRoom << endl;
}
void test01()
{
	Building b;
	goodGay(&b);
}
int main(){
	test01();
	system("pause");
	return 0;
}

2 類做友元

class Building;
class goodGay
{
public:
	goodGay();
	void visit();
private:
	Building *building;
};
class Building
{
	//告訴編譯器 goodGay類是Building類的好朋友,可以訪問到Building類中私有內(nèi)容
	friend class goodGay;
public:
	Building();
public:
	string m_SittingRoom; //客廳
private:
	string m_BedRoom;//臥室
};
Building::Building()
{
	this->m_SittingRoom = "客廳";
	this->m_BedRoom = "臥室";
}
goodGay::goodGay()
{
	building = new Building;
}
void goodGay::visit()
{
	cout << "好基友正在訪問" << building->m_SittingRoom << endl;
	cout << "好基友正在訪問" << building->m_BedRoom << endl;
}
void test01()
{
	goodGay gg;
	gg.visit();
}
int main(){
	test01();
	system("pause");
	return 0;
}

3 成員函數(shù)做友元

class Building;
class goodGay
{
public:
	goodGay();
	void visit(); //只讓visit函數(shù)作為Building的好朋友,可以發(fā)訪問Building中私有內(nèi)容
	void visit2(); 
private:
	Building *building;
};
class Building
{
	//告訴編譯器  goodGay類中的visit成員函數(shù) 是Building好朋友,可以訪問私有內(nèi)容
	friend void goodGay::visit();
public:
	Building();
public:
	string m_SittingRoom; //客廳
private:
	string m_BedRoom;//臥室
};
Building::Building()
{
	this->m_SittingRoom = "客廳";
	this->m_BedRoom = "臥室";
}
goodGay::goodGay()
{
	building = new Building;
}
void goodGay::visit()
{
	cout << "好基友正在訪問" << building->m_SittingRoom << endl;
	cout << "好基友正在訪問" << building->m_BedRoom << endl;
}
void goodGay::visit2()
{
	cout << "好基友正在訪問" << building->m_SittingRoom << endl;
	//cout << "好基友正在訪問" << building->m_BedRoom << endl;
}
void test01()
{
	goodGay  gg;
	gg.visit();
}
int main(){
	test01();
	system("pause");
	return 0;
}

運算符重載

運算符重載概念:對已有的運算符重新進行定義,賦予其另一種功能,以適應(yīng)不同的數(shù)據(jù)類型

1 加號運算符重載

作用:實現(xiàn)兩個自定義數(shù)據(jù)類型相加的運算

class Person {
public:
	Person() {};
	Person(int a, int b)
	{
		this->m_A = a;
		this->m_B = b;
	}
	//成員函數(shù)實現(xiàn) + 號運算符重載
	Person operator+(const Person& p) {
		Person temp;
		temp.m_A = this->m_A + p.m_A;
		temp.m_B = this->m_B + p.m_B;
		return temp;
	}
public:
	int m_A;
	int m_B;
};
//全局函數(shù)實現(xiàn) + 號運算符重載
//Person operator+(const Person& p1, const Person& p2) {
//	Person temp(0, 0);
//	temp.m_A = p1.m_A + p2.m_A;
//	temp.m_B = p1.m_B + p2.m_B;
//	return temp;
//}
//運算符重載 可以發(fā)生函數(shù)重載 
Person operator+(const Person& p2, int val)  
{
	Person temp;
	temp.m_A = p2.m_A + val;
	temp.m_B = p2.m_B + val;
	return temp;
}
void test() {
	Person p1(10, 10);
	Person p2(20, 20);
	//成員函數(shù)方式
	Person p3 = p2 + p1;  //相當(dāng)于 p2.operaor+(p1)
	cout << "mA:" << p3.m_A << " mB:" << p3.m_B << endl;
	Person p4 = p3 + 10; //相當(dāng)于 operator+(p3,10)
	cout << "mA:" << p4.m_A << " mB:" << p4.m_B << endl;
}
int main() {
	test();
	system("pause");
	return 0;
}

總結(jié)1:對于內(nèi)置的數(shù)據(jù)類型的表達式的的運算符是不可能改變的

總結(jié)2:不要濫用運算符重載

2 左移運算符重載

作用:可以輸出自定義數(shù)據(jù)類型

class Person {
	friend ostream& operator<<(ostream& out, Person& p);
public:
	Person(int a, int b)
	{
		this->m_A = a;
		this->m_B = b;
	}
	//成員函數(shù) 實現(xiàn)不了  p << cout 不是我們想要的效果
	//void operator<<(Person& p){
	//}
private:
	int m_A;
	int m_B;
};
//全局函數(shù)實現(xiàn)左移重載
//ostream對象只能有一個
ostream& operator<<(ostream& out, Person& p) {
	out << "a:" << p.m_A << " b:" << p.m_B;
	return out;
}
void test() {
	Person p1(10, 20);
	cout << p1 << "hello world" << endl; //鏈?zhǔn)骄幊?
}
int main() {
	test();
	system("pause");
	return 0;
}

總結(jié):重載左移運算符配合友元可以實現(xiàn)輸出自定義數(shù)據(jù)類型

3 遞增運算符重載

作用: 通過重載遞增運算符,實現(xiàn)自己的整型數(shù)據(jù)

class MyInteger {
	friend ostream& operator<<(ostream& out, MyInteger myint);
public:
	MyInteger() {
		m_Num = 0;
	}
	//前置++
	MyInteger& operator++() {
		//先++
		m_Num++;
		//再返回
		return *this;
	}
	//后置++
	MyInteger operator++(int) {
		//先返回
		MyInteger temp = *this; //記錄當(dāng)前本身的值,然后讓本身的值加1,但是返回的是以前的值,達到先返回后++;
		m_Num++;
		return temp;
	}
private:
	int m_Num;
};
ostream& operator<<(ostream& out, MyInteger myint) {
	out << myint.m_Num;
	return out;
}
//前置++ 先++ 再返回
void test01() {
	MyInteger myInt;
	cout << ++myInt << endl;
	cout << myInt << endl;
}
//后置++ 先返回 再++
void test02() {
	MyInteger myInt;
	cout << myInt++ << endl;
	cout << myInt << endl;
}
int main() {
	test01();
	//test02();
	system("pause");
	return 0;
}

總結(jié): 前置遞增返回引用,后置遞增返回值

4 賦值運算符重載

c++編譯器至少給一個類添加4個函數(shù)

  • 默認構(gòu)造函數(shù)(無參,函數(shù)體為空)
  • 默認析構(gòu)函數(shù)(無參,函數(shù)體為空)
  • 默認拷貝構(gòu)造函數(shù),對屬性進行值拷貝
  • 賦值運算符 operator=, 對屬性進行值拷貝

如果類中有屬性指向堆區(qū),做賦值操作時也會出現(xiàn)深淺拷貝問題

示例:

class Person
{
public:
	Person(int age)
	{
		//將年齡數(shù)據(jù)開辟到堆區(qū)
		m_Age = new int(age);
	}
	//重載賦值運算符 
	Person& operator=(Person &p)
	{
		if (m_Age != NULL)
		{
			delete m_Age;
			m_Age = NULL;
		}
		//編譯器提供的代碼是淺拷貝
		//m_Age = p.m_Age;
		//提供深拷貝 解決淺拷貝的問題
		m_Age = new int(*p.m_Age);
		//返回自身
		return *this;
	}
	~Person()
	{
		if (m_Age != NULL)
		{
			delete m_Age;
			m_Age = NULL;
		}
	}
	//年齡的指針
	int *m_Age;
};
void test01()
{
	Person p1(18);
	Person p2(20);
	Person p3(30);
	p3 = p2 = p1; //賦值操作
	cout << "p1的年齡為:" << *p1.m_Age << endl;
	cout << "p2的年齡為:" << *p2.m_Age << endl;
	cout << "p3的年齡為:" << *p3.m_Age << endl;
}
int main() {
	test01();
	//int a = 10;
	//int b = 20;
	//int c = 30;
	//c = b = a;
	//cout << "a = " << a << endl;
	//cout << "b = " << b << endl;
	//cout << "c = " << c << endl;
	system("pause");
	return 0;
}

5 關(guān)系運算符重載

**作用:**重載關(guān)系運算符,可以讓兩個自定義類型對象進行對比操作

示例:

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	};
	bool operator==(Person & p)
	{
		if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	bool operator!=(Person & p)
	{
		if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	string m_Name;
	int m_Age;
};
void test01()
{
	//int a = 0;
	//int b = 0;
	Person a("孫悟空", 18);
	Person b("孫悟空", 18);
	if (a == b)
	{
		cout << "a和b相等" << endl;
	}
	else
	{
		cout << "a和b不相等" << endl;
	}
	if (a != b)
	{
		cout << "a和b不相等" << endl;
	}
	else
	{
		cout << "a和b相等" << endl;
	}
}
int main() {
	test01();
	system("pause");
	return 0;
}

6 函數(shù)調(diào)用運算符重載

  • 函數(shù)調(diào)用運算符 () 也可以重載
  • 由于重載后使用的方式非常像函數(shù)的調(diào)用,因此稱為仿函數(shù)
  • 仿函數(shù)沒有固定寫法,非常靈活

示例:

class MyPrint
{
public:
	void operator()(string text)
	{
		cout << text << endl;
	}
};
void test01()
{
	//重載的()操作符 也稱為仿函數(shù)
	MyPrint myFunc;
	myFunc("hello world");
}
class MyAdd
{
public:
	int operator()(int v1, int v2)
	{
		return v1 + v2;
	}
};
void test02()
{
	MyAdd add;
	int ret = add(10, 10);
	cout << "ret = " << ret << endl;
	//匿名對象調(diào)用  
	cout << "MyAdd()(100,100) = " << MyAdd()(100, 100) << endl;
}
int main() {
	test01();
	test02();
	system("pause");
	return 0;
}

到此這篇關(guān)于C++深入探究類與對象之友元與運算符重載的文章就介紹到這了,更多相關(guān)C++友元內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt使用QChart實現(xiàn)靜態(tài)顯示溫度變化曲線

    Qt使用QChart實現(xiàn)靜態(tài)顯示溫度變化曲線

    QChart模塊是Qt?Charts庫的基礎(chǔ),提供了用于創(chuàng)建和顯示各種類型圖表的類和接口,本文主要介紹了如何使用QChart實現(xiàn)動態(tài)顯示3個設(shè)備的溫度變化曲線,感興趣的可以了解一下
    2023-06-06
  • VisualStudio?禁用移動文件到文件夾自動修改命名空間功能

    VisualStudio?禁用移動文件到文件夾自動修改命名空間功能

    這篇文章主要介紹了VisualStudio?禁用移動文件到文件夾自動修改命名空間功能,文章底部給大家介紹了解決安裝VS2022時,出現(xiàn)未能安裝包“Microsoft.VisualCpp.Redist.14,version=14.32.31332,chip”=x86,的問題及解決方法,需要的朋友可以參考下
    2022-09-09
  • Qt讀寫CSV文件的三種方式及優(yōu)劣對比

    Qt讀寫CSV文件的三種方式及優(yōu)劣對比

    最近的要用到CSV格式的數(shù)據(jù),所以這篇文章講述一下QT讀取CSV文件數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于Qt讀寫CSV文件的三種方式及優(yōu)劣對比的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • C++11中異常處理機制詳解

    C++11中異常處理機制詳解

    傳統(tǒng)的C語言處理異常的方式有兩種:終止程序和返回錯誤碼。在實際中的C語言程序基本都是通過返回錯誤碼的方式來處理錯誤的,部分情況下使用終止程序來處理比較嚴重的錯誤。本文將通過示例和大家聊聊C++11中異常處理機制,需要的可以參考一下
    2022-09-09
  • 淺析string 與char* char[]之間的轉(zhuǎn)換

    淺析string 與char* char[]之間的轉(zhuǎn)換

    與char*不同的是,string不一定以NULL('\0')結(jié)束。string長度可以根據(jù)length()得到,string可以根據(jù)下標(biāo)訪問。所以,不能將string直接賦值給char*
    2013-10-10
  • C++枚舉類型enum與enum class的使用

    C++枚舉類型enum與enum class的使用

    這篇文章主要介紹了C++枚舉類型enum與enum class的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 基于C語言實現(xiàn)http下載器

    基于C語言實現(xiàn)http下載器

    做OTA升級功能時,我們能直接拿到的往往只是升級包的鏈接,需要我們自己去下載,這時候就需要用到http下載器。本文將利用C語言實現(xiàn)簡單的http下載器,感興趣的可以了解一下
    2022-12-12
  • C語言運算符及其優(yōu)先級匯總表口訣

    C語言運算符及其優(yōu)先級匯總表口訣

    由于C語言的運算符優(yōu)先級與C++的不完全一樣(主要是增加了幾個運算符),所以這個口訣不能完全實用于C++.但是應(yīng)該能夠兼容,大家可以比較一下他們的區(qū)別應(yīng)該就能夠很快掌握C++的優(yōu)先級的
    2013-07-07
  • C語言實現(xiàn)學(xué)生打卡系統(tǒng)

    C語言實現(xiàn)學(xué)生打卡系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)學(xué)生打卡系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • C語言進階幾分鐘帶你理解大小端存儲模式

    C語言進階幾分鐘帶你理解大小端存儲模式

    這篇文章主要為大家介紹了C語言進階大小端模式的示例詳解,帶各位讀者朋友五分鐘腳踩大小端模式,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-02-02

最新評論