日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

指向类成员的指针

發布時間:2025/4/5 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 指向类成员的指针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

指向類成員的指針,印象中似乎很少用到,重新學習C++的過程中,才發現自己是忽視了一個很重要的東東,以前我一直認為類的成員函數不能作為回調函數,所以很多C程序都始終無法移植到C++上來,現在才知道,這是對指向類成員的指針不了解的緣故。


  1、指向非靜態成員的指針
  其實指向非靜態的類成員的指針很容易,它們與普通指針唯一的區別是,他們受類的限制。如下:
  class A
  {
   int _val;
   int val();
  };
  int (A::*p_val) = &A::_val;
  int ( A::*p_func )() = &A::val;
  看到了嗎,是的,和普通的指針的區別是,指向類成員的指針必須把類也一并帶上,上面的例子中就是要把A::這個限定符一起戴上,然后?用法和普通指針一樣的就是了。


  2、指向靜態成員的指針
  指向靜態成員的指針,聲明的方式和普通指針完全一樣,只是賦值的時候,還得加上類的限定符。為什么這樣?我想可以這樣來理解,對于非靜態成員,其存在取決于類,類消亡的時候,非靜態成員隨之消亡,所以,其聲明必須與類的限定符綁在一起,而靜態成員對于類而言并無依附關系,所以,不需要類的限定符。如下:
  class A
  {
   static int _val;
   static int val();
  };
  int *p_val = &A::_val;
  int (*p_func)() = &A::val;


  3、好處:
  一個好處是,通過指向成員的函數指針,可以很輕松的調用各個成員函數了;另一個好處是,對于靜態成員函數,可以成為C里的回調函數啦。


  下面是一個例子,加深一下理解:
  #include <iostream>
  #include <string>
  
  using namespace std;
  
  typedef void (*funchandler)();
  
  void register_func(funchandler f)
  {
   cout << "register_func" << endl;
   (*f)();
  }
  
  class A
  {
  public:
   A() : _val( 0 ) { cout << "create A..." << endl; }
   void test() { cout << "test..." << endl; }
   void test1() { cout << "test1..." << endl; }
   void test2() { cout << "test2..." << endl; }
   int val() { return _val; }
   static void test3() { cout << "test3..." << endl; }
   int _val;
  private:
  };
  
  
  
  int main()
  {
   A a;
   int ( A::*p_val ) = 0;
   p_val = &A::_val;
   cout << "a.*p_val: " << a.*p_val << endl;
  
   void (A::*p_func)();
   p_func = &A::test;
  
   a.test();
   (a.*p_func)();
  
   p_func = &A::test1;
   ( a.*p_func )();
   p_func = &A::test2;
   ( a.*p_func )();
  
   void (* pp_func)();
   pp_func = &A::test3;
   (*pp_func)();
  
   register_func( pp_func );
   return 0;
  }

?

 通過成員指針調用成員函數

可以在不必知道函數名的情況下,通過成員指針調用對象的成員函數。例如,函數dispatcher有一個變量pmf,通過它調用類成員函數,不管它調用的是strcpy()函數還是strcat()函數。指向外部原函數的指針和指向類成員函數的指針是有很大區別的。后者必須指向被調函數的宿主對象。因此,除了要有成員指針外,還要有合法對象或對象指針。

  現舉例做進一步說明。假設A有二個實例,成員函數指針支持多態性。這樣在成員指針調用虛成員函數時是動態處理的(即所謂后聯編 - 譯注)。注意,不可調用構造和析構函數。示例如下:

??? A?a1,?a2;

  A?
*p=?&a1;?//創建指向A的指針

  
//創建指向成員的指針并初始化

  
void?(A::*pmf)(char?*,?const?char?*)?=?&A::strcpy;

  
//要將成員函數綁定到pmf,必須定義呼叫的對象。

  
//可以用*號引導:

  
void?dispatcher(A?a,?void?(A::*pmf)(char?*,?const?char?*))

  {

   
char?str[4];

   (a.
*pmf)(str,?“abc”);?//將成員函數綁定到pmf

  }

  
//或用A的指針表達方式指向成員指針:

  
void?dispatcher(A?*?p,?void?(A::*pmf)(char?*,?const?char?*))

  {

   
char?str[4];?(p->*pmf)(str,?“abc”);

  }

  
//函數的調用方法為:

  dispatcher(a,?pmf);?
//?.*?方式

  dispatcher(
&a,?pmf);?//?->*?方式?

?

成員指針數組

class?A
{

  
public:

   
void?strcpy(char?*,?const?char?*);

   
void?strcat(char?*,?const?char?*);

};


  在下例,聲明了一個含有二個成員指針的數組,并分配類的成員函數地址給成員指針:

  typedef void(A::*PMA)(char *, const char *);

  PMA pmf[2]= {&A::strcpy, &A::strcat};?
也就是
????? void (A::*PMA[2])(char *, const char *)= {&A::strcpy, &A::strcat};

  這樣的數組在菜單驅動應用中很有用。選擇菜單項后,應用將調用相應的回叫函數,如下所示:

??? enum?MENU_OPTIONS?{?COPY,?CONCAT?};

  
int?main()
  {
   MENU_OPTIONS?option;?
char?str[4];
   
//從外部資源讀取選項
   
switch?(option)
   {
    
case?COPY:

     (pa
->*pmf[COPY])(str,?“abc”);

     
break;

    
case?CONCAT:

     (pa
->*pmf[CONCAT])(str,?“abc”);

     
break;

     
//

   }
  }?


?

Const 類型的成員函數

  成員指針的類型應該與成員函數類型一致。上面例子中的pmf 可以指向A的任意函數,只要該函數不是const類型。如下所示,如果將touppercase()的地址分配給pmf,將導致編譯出錯,因為touppercase() 的類型是const。

?? Class?A
  {

  
public:

   ?
void?strpcy(char?*,?const?char?*);

   
? void?strcat(char?*,?const?char?*);

   
? void?touppercase(char?*,?const?char*)?const;

  };

  pmf
=&A::touppercase;?//出錯,類型不匹配

  
//解決的方法是聲明一個const類型的成員指針:

  
void?(A::pcmf)(char?*,?const?char?*)?const;

  pcmf
=&A::touppercase;?//?現在可以了?



  有些差勁的編譯器允許一個非const類型的成員指針指向const類型的成員函數。這在標準C++是不允許的。

轉載于:https://www.cnblogs.com/weiqubo/archive/2011/03/22/1991364.html

總結

以上是生活随笔為你收集整理的指向类成员的指针的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。