C++类和对象--指向类成员的指针

1. 指向普通变量和函数的指针

#include <iostream>
using namespace std;
void func(int a)
{
    cout<<a<<endl;
}
int main()
{
    int a = 100;
    int *p = &a;
    cout<<*p<<endl;
    void (*pf)(int) = func;
    pf(10);
    return 0;
}

输出结果

2. 指向类数据成员的指针

2.1 定义

<数据类型><类名>::*<指针名>

2.2 赋值&初始化

<数据类型><类名>::*<指针名>[=&<类名>::<非静态数据成员>]

指向非静态数据成员的指针在定义时必须和类相关联,在使用时必须和具体的对象关联。

2.3 解引用

由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定类的一个对象,然后,通过对象来引用指针所指向的成员。

<类对象名>.*<指向非静态数据成员的指针>
<类对象指针>->*<指向非静态数据成员的指针>

2.4 案例

#include <iostream>
using namespace std;
class Student
{
public:
    Student(string n, int nu):name(n),num(nu){}
    string name;
    int num;
};
int main()
{
    Student s("zhangsan",1002);
    Student s2("lisi",1001);
    //string *ps = &s.name;//指向非静态数据成员的指针在定义时必须和类相关联
    //cout<< *ps<<endl;
    string Student::*ps = &Student::name;
    cout<<s.*ps<<endl;
    cout<<s2.*ps<<endl;
    Student *pp = new Student("wangwu",1003);
    cout<<pp->*ps<<endl;
    return 0;
}

输出结果

3. 指向类成员函数的指针

定义一个指向非静态成员函数的指针必须在三个方面与其指向的成员函数保持一致:参数列表要相同、返回类型要相同、所属的类型要相同。

3.1 定义

<数据类型>(<类名>::*<指针名>)(<参数列表>

3.2 赋值&初始化

<数据类型>(<类名>::*<指针名>)(<参数列表>)[=&<类名>::<非静态成员函数>]

3.3 解引用

由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定类的一个对象,然后,通过对象来引用指针所指向的成员。

(<类对象名>.*<指向非静态成员函数的指针>)(<参数列表>)
(<类对象指针>->*<指向非静态成员函数的指针>)(<参数列表>)

3.4 案例

#include <iostream>
using namespace std;
class Student
{
public:
    Student(string n, int nu):name(n),num(nu){}
    void dis()
    {
    cout<<"name "<<name<<" num "<<num<<endl;
}
private:
    string name;
    int num;
};
int main()
{
    Student s("zhangsan",1002);
    Student s2("lisi",1001);
    Student *ps = new Student("lisi",1003);
    void (Student::*pf)() = & Student::dis;
    (s.*pf)();
    (s2.*pf)();
    (ps->*pf)();
    return 0;
}

输出结果

3.5 应用之实现隐蔽接口

用指向类成员函数的指针,实现更加隐蔽的接口。

#include <iostream>
using namespace std;
class Widget
{
public:
    Widget()
    {
        fptr[0] = &Widget::f;
        fptr[1] = &Widget::g;
        fptr[2] = &Widget::h;
        fptr[3] = &Widget::i;
    }
    void select(int idx, int val)
    {
        if(idx<0 || idx>cnt) return;
        (this->*fptr[idx])(val);
    }
    int count()
    {
        return cnt;
    }
private:
    void f(int val){cout<<"void f() "<<val<<endl;}
    void g(int val){cout<<"void g() "<<val<<endl;}
    void h(int val){cout<<"void h() "<<val<<endl;}
    void i(int val){cout<<"void i() "<<val<<endl;}
    enum{ cnt = 4};
    void (Widget::*fptr[cnt])(int);
};
int main()
{
    Widget w;
    for(int i=0; i<w.count(); i++)
    {
        w.select(i,1);
    }
    return 0;
}

输出结果

4. 指向类静态成员的指针

  • 指向类静态数据成员的指针
    指向静态数据成员的指针的定义和使用与普通指针相同,在定义时无须和类相关联,在使用时也无须和具体的对象相关联。
  • 指向类静态成员函数的指针
    指向静态成员函数的指针和普通指针相同,在定义时无须和类相关联,在使用时也无须和具体的对象相关联。
#include <iostream>
using namespace std;
class A
{
public:
    static void dis();
    static int data;
};
void A::dis()
{
    cout<<data<<endl;
}
int A::data = 100;
int main()
{
    int *p = &A::data;
    cout<<*p<<endl;
    void (*pfunc)() = &A::dis;
    pfunc();
    return 0;
}

输出结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值