天天看點

面向對象程式設計 類 指向類的成員的指針

(文末附四種指針的使用方法對比)

1、指向類的非靜态資料成員的指針

//指針定義形式
類型說明符 類名::*指針名;
指針名=&類名::資料成員名;

//指針使用形式
對象名.*指針名
           

這樣指派以後的指針是不能使用的,隻有通過對象才能通路資料成員。

#include<iostream>
using namespace std;
class test
{
public:
	int x;
	test():x(0)
	{
	}
	test(int a):x(a)
	{
	}
	void disp()
	{
		cout<<"x="<<x<<endl;
	}
};
int main()
{
	test p(10);
	cout<<"p:";p.disp();
	int test::*q;
	q=&test::x;
	p.*q=20;
	cout<<"p:";p.disp();
}
/*result:
p:x=10
p:x=20
*/
           

main函數中

p.*q=20;

相當于令

p.x=20;

。需要注意的是,程式中資料成員為public域,否則編譯會有錯誤,因為main函數不能直接通路private資料成員。

2、指向類的非靜态成員函數的指針

//指針定義形式
類型說明符 (類名::*指針名)(參數表);
指針名=類名::成員函數名;

//指針使用形式
(對象名.*指針名)(參數表);
           

與指向非靜态資料成員的指針一樣,這樣定義的指針是不能使用的,必須通過對象來通路成員函數。

#include<iostream>
using namespace std;
class test
{
	int x;
public:
	test():x(0)
	{
	}
	test(int a):x(a)
	{
	}
	void setx(int a)
	{
		x=a;
	}
	void disp()
	{
		cout<<"x="<<x<<endl;
	}
};
int main()
{
	test p(10);
	cout<<"p:";p.disp();
	void (test::*q)(int);
	q=&test::setx;//setx函數後面沒有括号
	(p.*q)(20);//注意格式
	cout<<"p:";p.disp();
}
/*result:
p:x=10
p:x=20
*/
           

需要注意指向非靜态成員函數指針使用的格式

void (test::*q)(int);q=&test::setx;

注意setx函數後面沒有括号,當通過對象來通路成員函數的時候,也需要注意

(p.*q)(20);

格式。

3、指向類的靜态資料成員的指針

//指針定義形式
類型說明符 *指針名;
指針名=&類名::靜态資料成員名;

//指針使用形式
*指針名=x;
x=*指針名;//或者
           
#include<iostream>
using namespace std;
class test
{
	int x;
public:
	static int y;//靜态資料成員的聲明
	test():x(0)
	{
	}
	test(int a):x(a)
	{
	}
	void disp()
	{
		cout<<"x="<<x<<endl;
	}
};
int test::y=100;//靜态資料成員的定義
int main()
{
	int *p;
	p=&test::y;
	cout<<"y="<<*p<<endl;
}
/*result:
y=100
*/
           

還是要注意private域和public域。

4、指向類的靜态成員函數的指針

//指針定義形式
類型說明符 (*指針名)(參數表);
指針名=類名::靜态成員函數;

//指針使用形式
指針名(實際參數表);
(*指針名)(實際參數表);//或者
           
#include<iostream>
using namespace std;
class test
{
public:
	int x;
	static int y;
	test(int a,int b):x(a)
	{
		y=b;
	}
	static void sety(int s)
	{
		y=s;
	}
	void disp()
	{
		cout<<"x="<<x<<" "<<"y="<<y<<endl;
	} 
};
int test::y;
int main()
{
	void (*p)(int);
	p=test::sety;
	test q(10,10);
	p(20);
	q.disp();
} 
/*result:
x=10 y=20
*/
           

靜态成員函數隻能對靜态資料成員進行操作。

為了友善各種指針的使用方法,下面對四種指針的使用方法進行了彙總:

#include<iostream>
using namespace std;
class test
{
public://注意資料成員也為public域,否則無法通路,編譯錯誤 
	int x;
	static int y;//靜态資料成員 
public:
	test(int a,int b)
	{
		x=a;y=b;
	}
	void setx(int s)
	{
		x=s;
	}
	static void sety(int s)//靜态成員函數 
	{
		y=s;
	}
	void disp()
	{
		cout<<"x="<<x<<" "<<"y="<<y<<endl;
	}
};
int test::y;//靜态資料成員的定義 
int main()
{
	cout<<"//指向類的非靜态資料成員的指針"<<endl;
	int test::*p;
	p=&test::x;
	test pt(10,20);
	pt.*p=20;
	pt.disp();
	cout<<"//指向類的非靜态成員函數的指針"<<endl;
	void (test::*q)(int);
	q=test::setx;
	test qt(30,40);
	(qt.*q)(40);
	qt.disp();
	cout<<"//指向類的靜态資料成員的指針"<<endl;
	int *r;
	r=&test::y;
	test rt(50,60);
	cout<<"y="<<*r<<endl;
	cout<<"//指向類的靜态成員函數的指針"<<endl;
	void (*s)(int);
	s=test::sety;
	test st(70,80);
	s(70);
	st.disp();
}
/*result:
//指向類的非靜态資料成員的指針
x=20 y=20 
//指向類的非靜态成員函數的指針
x=40 y=40 
//指向類的靜态資料成員的指針
y=60 
//指向類的靜态成員函數的指針 
x=70 y=70
*/
           

繼續閱讀