C++知識點11——this指針,const成員函數,訪問權限控制

1.this指針

每個類都有this指針,this指針指向this指針指向的是類的對象本身

class A
{
public:
	A() {}
	~A() {}
	void func() {cout<<this<<endl;}
};

int main(int argc, char const *argv[])
{
	A t1,t2;
	cout<<&t1<<endl;
	t1.func();
	cout<<&t2<<endl;
	t2.func();
	return 0;
}

通過上述結果可知,this指針的值和類各自的對象的地址值相等。

 

當類的不同對象調用相同的成員函數時,會將this指針隱式傳入成員函數,從而可以根據this指針來操作相同的成員變量

void A::func2(int para)
{
	a=para;
	cout<<this->a<<endl;
}

int main(int argc, char const *argv[])
{
	A t1,t2;
	t1.func2(10);
	t2.func2(20);
	return 0;
}

t1和t2在第九行執行初始化時,自動調用了構造函數,將this指針初始化爲t1和t2的地址,在調用成員函數func2時,隱式地用自身的地址初始化this指針,同樣是打印this->a,實際上是打印t1.a和t2.a

所以通過this指針可以對同一個類的不同對象進行區分,防止類的不同對象的同名變量混淆

 

此外,在對象調用成員函數時,由編譯器自動隱式初始化this指針,所以不能顯示初始化this指針,而且,this指針一旦初始化完成,就會一直指向這個類的對象,所以this指針是個const指針

 

2.const成員函數

const成員函數就是在類的成員函數的形參列表後面加上const關鍵字,作用是將this指針指向的對象置爲const,所以,調用成員函數時,不能在const成員函數中修改類的對象

舉例

class A
{
public:
	A() {}
	~A() {}
	A constfunc() const;

private:
	int a;
};

A A::constfunc() const 
{
	cout<<__func__<<endl;
 //a=10;
	return *this;
}

int main(int argc, char const *argv[])
{
	A t1;
	A t2= t1.constfunc();
	return 0;
}

上述代碼中,類A的對象t2接收t1的拷貝,因爲返回了*this,如果想接收t1本身,那麼可以將函數的返回值定義爲類A的引用

如果將代碼15行解除註釋,就會產生如下錯誤

顯示成員變量a是隻讀的,如果將const修飾符去掉,則也能順利編譯通過

所以當有const修飾成員函數時,就不能在成員函數中對類的對象進行修改,

因爲有const修飾成員函數時,this指針指向的對象是const的,而成員變量變化時,表示類的對象變化,所以報錯

 

但是並不是所有的成員變量都不能在const成員函數中改變,如果一個成員變量用mutable來修飾,那麼該成員變量就可以在const成員函數中被修改

class A
{
public:
	A() {}
	~A() {}
	A constfunc() const;

private:
	mutable int m;
};

A A::constfunc() const 
{
	cout<<__func__<<endl;
	m=10;
	cout<<m<<endl;
	return *this;
}

int main(int argc, char const *argv[])
{
	A a;
	a.constfunc();
	return 0;
}

可見,編譯成功並且打印出m的值

 

此外,類的const對象和類的const對象的引用和指針只能調用const成員函數

舉例

class A
{
public:
	A() {}
	~A() {}
	void func2(int para);
	A constfunc() const;

private:
	int a;
};

void A::func2(int para)
{
	//a=para;
	cout<<this->a<<endl;
}

A A::constfunc() const 
{
	cout<<__func__<<endl;
	return *this;
}

int main(int argc, char const *argv[])
{
	const A a;
	a.func2(10);
	return 0;
}

因爲a是const對象,而非const成員函數有可能改變對象a中某些成員變量,所以報錯,const對象的指針和引用也是一樣,因爲const對象的指針和引用不能改變所綁定和指向的對象

 

3.訪問權限控制

上面代碼在類的定義的過程中都出現了public和private,public訪問控制符表示該訪問控制符下面的成員在整個程序中是可訪問的,而private訪問控制符表示該訪問符下面的成員只能在類中的成員函數中才能被訪問

class A
{
public:
	A() {}
	~A() {}

private:
	int a;
};

int main(int argc, char const *argv[])
{
	A a;
	cout<<a.a<<endl;
	return 0;
}

因爲a是私有的,main函數沒有訪問權,所以不能在main函數中使用,報錯

 

但是可以定義一個public的成員函數,在main函數中修改a的值並打印a

class A
{
public:
	A() {}
	~A() {}
	void seta(int i);

private:
	int a;
};

void A::seta(int i)
{
	a=i;
	cout<<a<<endl;
}

int main(int argc, char const *argv[])
{
	A a;
	a.seta(10);
	return 0;
}

對象a能夠調用seta函數,就是因爲seta是public的。

 

在C++中,class和struct都可以用來實現自己的類,它倆的唯一區別就是class定義的類,如果不加訪問權限說明符,那麼默認權限是private,而struct默認是public

 

參考:

《C++ Primer》

 

歡迎大家評論交流,作者水平有限,如有錯誤,歡迎指出

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