C++靜態成員函數和this指針詳解

靜態成員

靜態成員就是在成員變量和成員函數前加上關鍵字static,稱為靜態成員

靜態成員分為:

1.靜態成員變量

 所有對象共享同一份數據
 在編譯階段分配內存
 類內聲明,類外初始化

示例:

#include<iostream>
using namespace std;
class Person
{
public:
   static int m; // 所有對象共享同一份數據
};
int Person::m = 0;// 類內聲明,類外初始化

2.靜態成員函數

所有對象共享一個函數
靜態成員函數隻能訪問靜態成員變量
#include<iostream>
using namespace std;
class Person
{
public:
   static void func()
   {
   	cout << "static void func調用" << endl;
   	m_a = 100;//靜態成員函數可以訪問靜態成員變量
   	//m_b=100,靜態成員函數不可以訪問非靜態成員變量
   	//原因無法區分到底哪個是對象的m_b;
   }
   static int m_a;//靜態成員變量
   int m_b;
};
int Person::m_a = 0;
int main()
{
   //1.通過對象訪問
   Person p;
   p.func();
   //2.通過類名訪問
   Person::func();

   system("pause");
   return 0;
}

靜態成員函數可以訪問靜態成員變量

靜態成員函數不可以訪問非靜態成員變量

私有權限的靜態成員函數,也是訪問不到的

成員變量和成員函數分開存儲

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

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

空對象:

#include<iostream>
using namespace std;
class Person
{

};
void test01()
{
	Person p;
	//空對象占用內存空間為:1
	//C++編譯器會給每個空對象也分配一個字節空間,是為瞭區分空對象占內存的位置
	//每個空對象也應該有獨一無二的內存地址
	cout << sizeof(p) << endl;
}
int main()
{
	test01();
	return 0;
}

輸出結果:1

#include<iostream>
using namespace std;
class Person
{
	int m_a;//非靜態成員變量 屬於類的對象上
};
void test02()
{
	Person p;
	cout << sizeof(p) << endl;
}
int main()
{
	test02();
}

輸出結果:4

#include<iostream>
using namespace std;
class Person
{
	int m_a;//非靜態成員變量 屬於類的對象上
	static int m_b; //靜態成員變量 不屬於類的對象上
};
void test02()
{
	Person p;
	cout << sizeof(p) << endl;
}
int main()
{
	test02();
}

輸出結果:4

與第二個對比可知:

靜態成員變量 不屬於類的對象上

#include<iostream>
using namespace std;
class Person
{
	int m_a;//非靜態成員變量 屬於類的對象上
	static int m_b; //靜態成員變量 不屬於類的對象上
	void func() {}//非靜態成員函數 不屬於類的對象上
	static void func2() {} //靜態成員函數也不會屬於 類的對象上
};
 int Person::m_b = 0;
void test02()
{
	Person p;
	cout << sizeof(p) << endl;
}
int main()
{
	test02();
}

輸出結果:4

結論:隻有非靜態成員變量才屬於類的對象上

this 指針

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

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

C++通過提供的特殊的對象指針,this指針,解決上述問題,this 指針指向被調用的成員函數所屬的對象,通俗的說,誰調用它,this就指向誰

this 指針是所有成員函數的隱含參數嗎,不需要定義,可直接使用

this 指針的用途

1.當形參和成員變量同名時,可用this指針來區分
2.在類的非靜態成員函數中返回對象本身,可用 return  *this 

1.當形參和成員變量同名時,可用this指針來區分

#include<iostream>
using namespace std;
class Person
{
public:
	void func(int age)
	{
		this->age = age;  //
	}
	int age;
};
int main()
{
	Person p;
	p.func(18);
	cout << p.age << endl;
	system("pause");
	return 0;
}

2.在類的非靜態成員函數中返回對象本身,可用 return *this

#include<iostream>
using namespace std;
class Person
{
public:
	Person& func(Person&p)
	{
		this->age += p.age;
		return *this;
	}
	int age;
};
int main()
{
	Person p;
	p.age = 10;
	//鏈式編程思想
	p.func(p).func(p).func(p);
	cout << p.age << endl;
	system("pause");
	return 0;
}

空指針訪問成員函數

C++中空指針是可以調用成員函數,但是也要註意有沒有用到this指針

如果用到this指針,需要加以判斷保證代碼的健壯性

#include<iostream>
using namespace std;
class Person
{
public:
	void ShowPersonclass()
	{
		cout << "調用ShowPerclass()函數" << endl;
	}
};
int main()
{
	Person* p = NULL;
	p->ShowPersonclass();
	system("pause");
	return 0;
}

通過空指針p是可以訪問到成員函數(不帶this指針的成員函數)

如下代碼就是一個錯誤代碼

#include<iostream>
using namespace std;
class Person
{
public:
	void ShowPersonname()
	{
		cout << m_name << endl;  //此處出現瞭this指針
	}
	int m_name;
};
int main()
{
	Person* p = NULL;
	p->ShowPersonname();
	system("pause");
	return 0;
}

解析:

此處出現瞭this指針

cout << m_name << endl;

相當於

cout <<this -> m_name << endl;

而this指針是一個空指針,所以會報錯

為瞭增加代碼的健壯性,我們因該做出如下改動

#include<iostream>
using namespace std;
class Person
{
public:
	void ShowPersonname()
	{
		if (this == NULL)  //在此判斷this是否是空指針
			return;
		cout << m_name << endl;
	}
	int m_name;
};
int main()
{
	Person* p = NULL;
	p->ShowPersonname();
	system("pause");
	return 0;
}

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: