C++成员指针 int A::*

成员指针

首先感谢知乎大大为我指点迷津
https://www.zhihu.com/question/51441745?from=profile_question_card

一、注意成员指针不是指针

引用大大的话,成员指针是:

在一个对象内部定位某一个成员的方式

首先我尝试输出成员指针的值:

class A
{
public:
    int x;
    int y;
};

int main()
{
    int A::*p = &A::x;
    A a = {20,30};
    cout << a.*p << endl;//输出20
    cout << p << endl;//1
    p = &A::y;
    cout << p << endl;//1
    p = 0;
    cout << p << endl;//0
}

….你是bool变量吗,之后我通过下断点在编译器里看到了它的值

int main()
{
    int A::*p = &A::x;
    A a = {20,30};
    cout << p << endl;//&A::x
    p = &A::y;
    cout << p << endl;//&A::y
    p = 0;
    cout << p << endl;//NULL
}

可以,不知道它具体的值是多少,反正不是个指针

一些愚蠢的尝试(接上文)

p = &A::x
void *pp = *(int**)&p;
cout << pp << endl;//0
void *pp = *(void**)&p;
cout << pp << endl;//0

二、基本功能

之后的代码都是用的类A

int A::*p = &A::x;
A a = {20,30};
cout << a.*p << endl;//20
a.*p = 100;//等同于 a.x = 100
cout << a.*p << endl;//100

A *aa = &a;
cout << aa->*p << endl;//100
aa->*p = 200;//等同于 a->x = 200
cout << aa->*p << endl;//200

三、父子类的情况

增加一子类B

class B:public A
{
public:
    int z;
};
int A::*p = &A::x;
int B::*q = &B::x;

A a = {20,30};
B b;
b.x = 21;
b.y = 31;

cout << a.*p << endl;//20
cout << b.*p << endl;//21
cout << a.*q << endl;//error
cout << b.*q << endl;//21

p = &B::x;//可行且值仍为&A::x
p = &B::z;//无法将‘int B::*’转为‘int A::*’
q = &A::x;//可行且值为&A::x

可预知的,无法在父类中使用子类的成员指针,毕竟子类会比父类多一些成员。
此外,我们发现只要是指向父类成员的指针,其值一直为”int A::*?”,在上述例子中无论对q,p怎样赋值,只要其指向x,y时,就只会出现值“&A::x”,“&A::y“。

四、成员函数指针

对类A进行修改

class A
{
public:
    int x;
    int y;

    void fun(){cout << "A.x:" << x <<endl;}
};
void (A::*pFun)() = &A::fun;

A a = {12,13};
(a.*pFun)();//A.x:12

成员函数指针的其他情况大多与成员指针一致。注意,不可调用构造和析构函数。
此外,面对参数太多,太过复杂的函数,我们可以寻求auto的帮助(太棒啦):

auto pp = &A::fun;
(a.*pp)();//A.x:12

五、与模板的互动

template<typename T>
class IsClass
{
private:
    typedef char One;
    typedef struct { char a[2]; } Two;

    template<typename C>
    static One test(int C::*) {}

    template<typename C>
    static Two test(...) {}

public:
    enum { Yes = sizeof(test<T>(0)) == 1 };
};
int main()
{
    IsClass<int> m;
    cout << m.Yes << endl;

    IsClass<A> n;
    cout << n.Yes << endl;

    return 0;
}

如果类型T是一个类,那么0就会匹配”int C::*”类型,以此区分一个类型是不是一个类。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值