【C++的面向對象】const和mutable的曖昧

1、const可以實現常函數
(1)常函數,就是class的成員函數承諾在函數內部不會修改class的任何成員變量,注意是任何一個
(2)常函數演示案例

#include <string>
#include <iostream>
using namespace std;

/*****************定義一個類***********************/
class person
{

public:
	string name;			// 名字
	bool male;			// 性別,男爲true,女爲false
	
	person(){};
	person(int myage);
	
	void AgeAdd1(void);
	int AgeGet(void) const;       //定義爲常函數,編寫類的人承諾在這個函數裏面不會修改任意一個成員變量
	
private:
    int age;				     // 年齡
};

/****************實現類方法*************************/

person::person(int myage)        //自定義構造函數
{
	this->age = myage;
}		

// 人長大了一歲,所以age++,所以這個方法不是一個常函數,因爲內部改變了成員變量的值
void person::AgeAdd1(void)
{
	this->age++;
}

// 本函數只是讀取class的成員變量,並不修改,所以可以是常函數
int person::AgeGet(void) const
{
	//age++;
	return this->age;
}

/*****************類的使用者******************/
// 對於person類的使用者,使用類的時候會封裝一些函數來完成功能,函數傳參的時候會用引用
void PrintAge(const person& pn)
{
	// 寫PrintAge函數的人,心裏很清楚,AgeGet的調用絕對不會修改pn對象的任何一個成員變量
	cout <<"person.age = " << pn.AgeGet() << endl;
}

int main(void)
{
	person p1(23);	
	//p1.AgeAdd1();		// 寫main函數的人,調用這個方法時,心裏很清楚有可能會修改p1對象的成員變量
	PrintAge(p1);
	return 0;
}

在上面的例子中int AgeGet(void) const; 定義爲常函數,編寫類的人承諾在這個函數裏面不會修改任意一個成員變量;所以在調用這個方法的時候寫PrintAge函數的人,心裏很清楚,AgeGet的調用絕對不會修改pn對象的任何一個成員變量。

現在我們嘗試在聲明爲const常函數裏面修改成員變量:

// 本函數只是讀取class的成員變量,並不修改,所以可以是常函數
int person::AgeGet(void) const
{
	age++;       //改變成員變量的值
	return this->age;
}

在這裏插入圖片描述
總結:上例中const函數調用存在一個承諾鏈條:在使用類庫的人中,它實現了一個方法void PrintAge(const person& pn),它向main()函數承諾,我不會修改你給我傳的參數即引用,所以main()函數中,person p1(23); PrintAge(p1);而在PrintAge(const person& pn)裏面的pn.AgeGet() ;函數就向PrintAge承諾我不會在AgeGet()函數裏面修改成員變量的值,所以你調用我的時候也要傳const的參數。

(3)思考:C++爲什麼設計常函數?是爲了class的設計者和使用者更好的協作,避免錯誤的使用類庫

2、mutable可以局部打破const常函數
(1)const常函數承諾在函數內不會修改class的任何一個成員變量
(2)但是有時候個別成員變量,就是需要在const的常函數中也能修改(注意只是個別,其他大部分是不需要修改的
(3)怎麼辦?2個解法:要麼去掉const,要麼使用mutable局部打洞
(4)mutable使用演示

定義類的時候用mutable修飾想要在const函數中訪問的成員變量

class person
{

public:
	mutable string name;			//  給name 成員變量打洞
	bool male;			// 性別,男爲true,女爲false
	
	person(){};
	person(int myage);
	
	void AgeAdd1(void);
	int AgeGet(void) const;       //定義爲常函數,編寫類的人承諾在這個函數裏面不會修改任意一個成員變量
	
private:
    mutable int age;				     // 給age成員打洞
};

在const函數中可以改變mutable修飾的成員變量

int person::AgeGet(void) const
{
	age++;
	name = "ddd";  
	return this->age;
}

在這裏插入圖片描述

(5)思考:C++爲什麼設計mutable?和private那裏一樣,還是先全部禁了再按需打開的思路

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章