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

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

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

友元

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

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

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

友元的關鍵字為: friend

友元的三種實現:

  • 全局函數做友元
  • 類做友元
  • 成員函數做友元

1 全局函數做友元

class Building
{
	//告訴編譯器 goodGay全局函數 是 Building類的好朋友,可以訪問類中的私有內容
	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類中私有內容
	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 成員函數做友元

class Building;
class goodGay
{
public:
	goodGay();
	void visit(); //只讓visit函數作為Building的好朋友,可以發(fā)訪問Building中私有內容
	void visit2(); 
private:
	Building *building;
};
class Building
{
	//告訴編譯器  goodGay類中的visit成員函數 是Building好朋友,可以訪問私有內容
	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;
}

運算符重載

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

1 加號運算符重載

作用:實現兩個自定義數據類型相加的運算

class Person {
public:
	Person() {};
	Person(int a, int b)
	{
		this->m_A = a;
		this->m_B = b;
	}
	//成員函數實現 + 號運算符重載
	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;
};
//全局函數實現 + 號運算符重載
//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ā)生函數重載 
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);
	//成員函數方式
	Person p3 = p2 + p1;  //相當于 p2.operaor+(p1)
	cout << "mA:" << p3.m_A << " mB:" << p3.m_B << endl;
	Person p4 = p3 + 10; //相當于 operator+(p3,10)
	cout << "mA:" << p4.m_A << " mB:" << p4.m_B << endl;
}
int main() {
	test();
	system("pause");
	return 0;
}

總結1:對于內置的數據類型的表達式的的運算符是不可能改變的

總結2:不要濫用運算符重載

2 左移運算符重載

作用:可以輸出自定義數據類型

class Person {
	friend ostream& operator<<(ostream& out, Person& p);
public:
	Person(int a, int b)
	{
		this->m_A = a;
		this->m_B = b;
	}
	//成員函數 實現不了  p << cout 不是我們想要的效果
	//void operator<<(Person& p){
	//}
private:
	int m_A;
	int m_B;
};
//全局函數實現左移重載
//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; //鏈式編程
}
int main() {
	test();
	system("pause");
	return 0;
}

總結:重載左移運算符配合友元可以實現輸出自定義數據類型

3 遞增運算符重載

作用: 通過重載遞增運算符,實現自己的整型數據

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; //記錄當前本身的值,然后讓本身的值加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;
}

總結: 前置遞增返回引用,后置遞增返回值

4 賦值運算符重載

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

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

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

示例:

class Person
{
public:
	Person(int age)
	{
		//將年齡數據開辟到堆區(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 關系運算符重載

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

示例:

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 函數調用運算符重載

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

示例:

class MyPrint
{
public:
	void operator()(string text)
	{
		cout << text << endl;
	}
};
void test01()
{
	//重載的()操作符 也稱為仿函數
	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;
	//匿名對象調用  
	cout << "MyAdd()(100,100) = " << MyAdd()(100, 100) << endl;
}
int main() {
	test01();
	test02();
	system("pause");
	return 0;
}

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

相關文章

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

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

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

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

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

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

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

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

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

    淺析string 與char* char[]之間的轉換

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

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

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

    基于C語言實現http下載器

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

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

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

    C語言實現學生打卡系統(tǒng)

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

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

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

最新評論