c++學習筆記3--this指針,友元

1. C++對象模型和this指針

1.1 成員變量和成員函數分開存儲
在C++中,類內的成員變量和成員函數分開存儲

只有非靜態成員變量才屬於類的對象上

class Person {
public:
	Person() {
		mA = 0;
	}
	//非靜態成員變量佔對象空間
	int mA;
	//靜態成員變量不佔對象空間
	static int mB; 
	//函數也不佔對象空間,所有函數共享一個函數實例
	void func() {
		cout << "mA:" << this->mA << endl;
	}
	//靜態成員函數也不佔對象空間
	static void sfunc() {
	}
};

int main() {

	cout << sizeof(Person) << endl;

	system("pause");

	return 0;
}

1.2 this指針概念

通過4.3.1我們知道在C++中成員變量和成員函數是分開存儲的

每一個非靜態成員函數只會誕生一份函數實例,也就是說多個同類型的對象會共用一塊代碼

那麼問題是:這一塊代碼是如何區分那個對象調用自己的呢?

c++通過提供特殊的對象指針,this指針,解決上述問題。this指針指向被調用的成員函數所屬的對象

this指針是隱含每一個非靜態成員函數內的一種指針

this指針不需要定義,直接使用即可

this指針的用途:

  • 當形參和成員變量同名時,可用this指針來區分
  • 在類的非靜態成員函數中返回對象本身,可使用return *this
class Person
{
public:

	Person(int age)
	{
		//1、當形參和成員變量同名時,可用this指針來區分
		this->age = age;
	}

	Person& PersonAddPerson(Person p)
	{
		this->age += p.age;
		//返回對象本身
		return *this;
	}

	int age;
};

void test01()
{
	Person p1(10);
	cout << "p1.age = " << p1.age << endl;

	Person p2(10);
	p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
	cout << "p2.age = " << p2.age << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

1.3 空指針訪問成員函數

//空指針訪問成員函數
class Person {
public:

	void ShowClassName() {
		cout << "我是Person類!" << endl;
	}

	void ShowPerson() {
		if (this == NULL) {
			return;
		}
		cout << mAge << endl;
	}

public:
	int mAge;
};

void test01()
{
	Person * p = NULL;
	p->ShowClassName(); //空指針,可以調用成員函數
	p->ShowPerson();  //但是如果成員函數中用到了this指針,就不可以了
}

int main() {

	test01();

	system("pause");

	return 0;
}

1.4 const修飾成員函數
常函數:

  • 成員函數後加const後我們稱爲這個函數爲常函數

  • 常函數內不可以修改成員屬性

  • 成員屬性聲明時加關鍵字mutable後,在常函數中依然可以修改
    常對象

  • 聲明對象前加const稱該對象爲常對象

  • 常對象只能調用常函數

class Person {
public:
	Person() {
		m_A = 0;
		m_B = 0;
	}

	//this指針的本質是一個指針常量,指針的指向不可修改
	//如果想讓指針指向的值也不可以修改,需要聲明常函數
	void ShowPerson() const {
		//const Type* const pointer;
		//this = NULL; //不能修改指針的指向 Person* const this;
		//this->mA = 100; //但是this指針指向的對象的數據是可以修改的

		//const修飾成員函數,表示指針指向的內存空間的數據不能修改,除了mutable修飾的變量
		this->m_B = 100;
	}

	void MyFunc() const {
		//mA = 10000;
	}

public:
	int m_A;
	mutable int m_B; //可修改 可變的
};


//const修飾對象  常對象
void test01() {

	const Person person; //常量對象  
	cout << person.m_A << endl;
	//person.mA = 100; //常對象不能修改成員變量的值,但是可以訪問
	person.m_B = 100; //但是常對象可以修改mutable修飾成員變量

	//常對象訪問成員函數
	person.MyFunc(); //常對象能調用const的函數

}

int main() {

	test01();

	system("pause");

	return 0;
}

2.友元

生活中你的家有客廳(Public),有你的臥室(Private)

客廳所有來的客人都可以進去,但是你的臥室是私有的,也就是說只有你能進去

但是呢,你也可以允許你的好閨蜜好基友進去。

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

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

友元的關鍵字爲 friend

友元的三種實現

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

2.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.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;
}

2.3 成員函數做友元

class Building;
class goodGay
{
public:

	goodGay();
	void visit(); //只讓visit函數作爲Building的好朋友,可以發訪問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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章