程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++拾遺

C++拾遺

編輯:關於C++

C++拾遺--類成員指針

前言

類成員的類型與一般類型不同,那麼類成員的指針類型自然與一般類型的指針有所區別。我們有必要來探討下類成員指針的使用。

正文

類成員指針是指可以指向類的非靜態成員的指針。它的類型包括了類類型和所指向的成員類型。一般而言,指針指向的是對象,而類成員指針指向的是類成員而非類對象。

需要指出,類成員指針不是可調用對象,要想通過類成員指針調用類成員,需結合類對象或類指針。靜態類型成員屬於類,類型與普通指針相似。

數據成員指針

一般的聲明形式:

成員類型 classname::*p;

它的賦值形式:

p = &classname::類數據成員;

這裡的取地址符&,是必須的。

 

#include 
using namespace std;
class Myclass
{
public:
	int a;
	const char c;
	Myclass(int a, int c) :a(a), c(c)
	{

	}
};
int main(void)
{
	int Myclass::*pa;
	pa = &Myclass::a;

	const char Myclass::*pc;
	pc = &Myclass::c;

	Myclass my(520, 'C'), *p = &my;
	cout << my.*pa << endl;
	cout << p->*pa << endl;
	cout << my.*pc << endl;
	cout << p->*pc << endl;
	cin.get();
	return 0;
}
運行

 

\
 

在這個例子中,我們定義了兩個成員指針pa和pc。其中pc的聲明必須加上const,否則,稍後的賦值會發生類型不匹配的錯誤。我們還定義了類的對象和指針,它們分別通過成員指針訪問運算符.*和->*,對類成員指針進行訪問。

 

函數成員指針

和數據成員指針類似,它的聲明同樣得指定類類型和函數成員類型。

返回類型 (classname::*pfun)(參數類型列表);

 

它的賦值形式:

pfun = &classname::類函數成員;

 

#include 
using namespace std;
class Compute
{
public:
	int add(int a, int b)
	{
		return a + b;
	}
	int sub(int a, int b) const
	{
		return a - b;
	}
};
int main(void)
{
	int (Compute::*pfun1)(int, int);
	pfun1 = &Compute::add;
	
	int (Compute::*pfun2)(int, int) const;
	pfun2 = &Compute::sub;
	
	Compute com, *p = &com;
	cout << (com.*pfun1)(100, 10) << endl;
	cout << (p->*pfun1)(100, 10) << endl;
	cout << (com.*pfun2)(100, 10) << endl;
	cout << (p->*pfun2)(100, 10) << endl;
	cin.get();
	return 0;
}
運行

 

\
 

這個例子就不多解釋了。只說一句:訪問限定符仍然有效,可在類外訪問的數據和函數才可以使用類成員指針調用。

 

mem_fn

通過mem_fn對類函數成員指針進行包裝,來返回一個可調用對象。使用時,包含頭文件functional。

 

#include 
#include 
using namespace std;
class Compute
{
public:
	Compute(int a, int b) :a(a), b(b)
	{

	}
	int add()
	{
		return a + b;
	}
	int sub() const
	{
		return a - b;
	}
private:
	int a;
	int b;
};
int main(void)
{
	Compute com(100, 10), *p = &com;
	auto fun1 = mem_fn(&Compute::add);
	cout << fun1(com) << endl;
	cout << fun1(p) << endl;
	auto fun2 = mem_fn(&Compute::sub);
	cout << fun2(com) << endl;
	cout << fun2(p) << endl;
	cin.get();
	return 0;
}
運行

 

\

由於add方法是參數是void的,所有調用時,只傳遞類對象fun(com)或指針fun(p)即可。

若成員方法是帶參數的,該如何使用呢?看下面的代碼:

 

#include 
#include 
using namespace std;
class Compute
{
public:
	int add(int a, int b)
	{
		return a + b;
	}
	int sub(int a, int b) const
	{
		return a - b;
	}
};
int main(void)
{
	Compute com, *p = &com;
	auto fun1 = mem_fn(&Compute::add);
	cout << fun1(com, 100, 10) << endl;
	cout << fun1(p, 110, 10) << endl;
	auto fun2 = mem_fn(&Compute::sub);
	cout << fun2(com, 120, 10) << endl;
	cout << fun2(p, 130, 10) << endl;
	cin.get();
	return 0;
}
運行

 

\

這個示例顯示了,若是帶參數的,參數跟在類對象或類指針後面即可。

mem_fn會根據傳入的參數類型,自動選擇調用.*或->*:

Compute com, *p = &com;

auto fun = mem_fn(&Compute::add);

fun(com);//傳入對象,這一句會被解釋成 auto padd = &Compute::add;(com.*padd)();

fun(p); //傳入指針,這一句會被解釋成 auto padd = &Compute::add;(p->*padd)();

 

bind

使用函數適配器bind,綁定類函數成員,返回可調用對象。

在bind函數綁定中,已經有了詳細介紹。


 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved