c++指向类(非)静态成员的指针用法 && C++中怎么获取类的成员函数的函数指针?

#include <iostream>

using namespace std;

class Test {
public:
    Test():x(0), y(0)
    {
        cnt++;
    }
    int x;
    int y;
    void print() const;
    static int cnt;
    static void print_s();              //静态成员函数不能够设置为const函数 ( static member function cannot have cv qualifier??? cv 限定符 即 const and volatile)
};

int Test::cnt = 0;                      //静态成员变量的初始化

void Test::print_s()
{
    cout<<cnt<<" object(s) has(have) been created"<<", visited by print_s function"<<endl;
}

void Test::print() const
{
    cout<<"x = "<<x<<" y = "<<y<<endl;
}
int main()
{
    int Test::*ptr;                     //声明指向类非静态成员变量的指针
    void (Test::*print_p)() const;      //声明指向类非静态成员函数的指针
    print_p = &Test::print;             //赋值
    ptr = &Test::x;                     //赋值
    Test a;
    a.*ptr = 1;                         //调用
    (a.*print_p)();                     //调用,前面的括号不能掉(运算符的优先级)

    int *ptr_1 = &Test::cnt;            //声明和初始化指向类静态成员变量的指针
    cout<<*ptr_1<<" object(s) has(have) been created"<<", visited by pointer"<<endl;    //通过指针访问静态成员变量
    Test::print_s();                    //通过静态成员函数访问静态成员变量
    return 0;
}

用一个实际代码来说明。

  1. class A
  2. {
  3. public:
  4.     static void staticmember() { cout<<"static"<<endl; }    //static member
  5.     void nonstatic() { cout<<"nonstatic"<<endl; }    //nonstatic member
  6.     virtual void virtualmember() { cout<<"virtual"<<endl; };    //virtual member
  7. };
  8.  
  9. int main()
  10. {
  11.     A a;
  12.     //static成员函数,取得的是该函数在内存中的实际地址,而且因为static成员是全局的,所以不能用A::限定符
  13.     void(*ptrstatic)()=&A::staticmember;      
  14.     //nonstatic成员函数 取得的是该函数在内存中的实际地址    
  15.     void(A::*ptrnonstatic)()=&A::nonstatic;
  16.     //虚函数取得的是虚函数表中的偏移值,这样可以保证能过指针调用时同样的多态效果
  17.     void(A::*ptrvirtual)()=&A::virtualmember;
  18.  
  19.     //函数指针的使用方式
  20.     ptrstatic();
  21.     (a.*ptrnonstatic)();
  22.     (a.*ptrvirtual)();
  23. }

可以参考《C++ Primer(3rd)》第532页13.6指向类成员的指针一节~

 

 

1.一个指向外部函数的指针声明为:

  1. void(*pf)(char*,constchar*);
  2. void strcpy(char* dest,constchar* source);
  3. pf=strcpy;

2.一个指向类A成员函数的指针声明为

  1. void(A::*pmf)(char*,constchar*);

声明的解释是:pmf是一个指向A成员函数的指针,返回无类型值,函数带有二个参数,参数的类型分别是char * 和 const char *。除了在星号前增加A:: ,与声明外部函数指针的方法一样。

3.给成员指针赋值的方法是将函数名通过指针符号&赋予指针名
如下所示:

    1. class A
    2. {
    3.  
    4.   public:
    5.  
    6.    void strcpy(char*,constchar*);
    7.  
    8.    void strcat(char*,constchar*);
    9.  
    10. };
    11.  
    12. pmf =&A::strcpy;
    13. 比较pmf=&A::strcpy与pmf=A::strcpy,为什么pmf=A::strcpy会报错!
    14. 函数名并不是函数地址的代表,这种误解与数组名就是指针一样犯了相同的错误。函数名是函数实体的代表,不是地址的代表,当然,你马上就会有疑问,平时我们不都是把函数名作为函数的地址吗?是的,我可以告诉你,函数名可以作为函数的地址,但是,绝大多数人都忽略了一个条件,从函数到指针的隐式转换是函数名在表达式中的行为,就是说,这个转换仅在表达式中才会发生,这仅是函数名众多性质中的一个,而非本质,函数名的本质就是函数实体的代表。到了C++,由于C++规定,非静态成员函数的左值不可获得,因此非静态成员函数不存在隐式左值转换,即不存在像常规函数那样的从函数到指针的隐式转换,所以必须在非静态成员函数前使用&操作符才能获得地址。

转载处:

https://www.cnblogs.com/rocklee25/p/7401158.html

https://www.cnblogs.com/lidabo/p/3597559.html

https://bbs.csdn.net/topics/390573179?page=1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值