Pointers to Class Members Are Not Pointers(指向类成员函数的“指针”并非指针)

Item 15. Pointers to Class Members Are Not Pointers


Pointers to Class Members:指向类成员的指针

注:本条中只涉及到非静态的数据成员
--------------------------------------------------------
1、类成员的指针之声明:
 class C {
  public:
    //...
    int a_;
 };
 int C::*pimC; //指向类C成员的指针,这里只是声明

2、类成员的指针之含义:
 
 类成员的指针用“指针”这个词来描述很容易引起混淆,因为类成员的指针和指针的含义大相径庭:
指针包含地址;而类成员的指针并不涉及到内存地址,它只是引用了一个类的某个成员,而不是一个具体的对象的某个成员,类没有内存地址,因此类成员的指针也不能指向内存的某个地方,它通常只是一个偏移量(offset)。然而由于标准C++没有定义类成员的指针的实现,因此各个编译器厂家的实现也不尽相同,但大多数是用一个整数来表示这个偏移量。

  pimC = &C::a_;   //获取成员a_在C中的偏移量,如果a_为静态成员则pimC指向C::a_的地址;如果a_为非静态成员则pimC代表此非静态成员在类当中的偏移量(一个整形的值)
 
3、访问偏移量对应的数据成员
  C aC;
  C *pC = &aC;
  aC.*pimC = 0;    //*pimC应用到了C的每一个对象上
  int b = pC->*pimC;
  有了一个类成员的偏移量,为了取得在这个偏移量上的数据成员,我们就需要该类的一个对象的地址。于是,“.*”和“->*”就粉墨登场了。
  aC.*pimC的含义: 访问对象aC在偏移量为pimC上的数据成员
  pC->*pimC的含义: 访问指针pC指向的对象在偏移量为pimC上的数据成员

4、当继承出现后……
  在继承体系中,子类对象的指针可以隐式的转换位父类对象的指针,反之需要显示的转换。
  但类成员的指针转换规则恰恰相反。
  不用奇怪,大家都遵循同一的规则:父类有的子类肯定有,子类有的父类未必有。
 
 class Shape {
    //...
    Point center_;
    //...
};
class Circle : public Shape {
    //...
    double radius_;
    //...
};

Point Circle::*loc = &Shape::center_; // OK
//double Shape::*extent =&Circle::radius_; // error!     

成员指针类型的转换必须要先用成员指针的类型变量把它存储,然后再把成员指针类型转换成其他的类型(最好时转换成int*)

还是举个例子吧:

 

#define MEMBER_OFFSET(type, member) ((unsigned long) (&((type*)0)->member))

Point

{

    //...

    int x,y,z....;

    //

};

 

int Point::* pim;

int main()

{

    Point obj;

    pim = &Point::z;   //关键

    //int *tmp = (int *) &Point::z;  这个是怎么转也转不过来的

    printf("&obj.z= %p/t&obj+&Point::z = %p/n", &obj.z, reinterpret_cast<char *>(&obj) + *(char *)(&pim));

    //第二种方式转换

    unsigned log = MEMBER_OFFSET(Point, z);

    printf(("&obj.z= %p/t&obj+&Point::z = %p/n", &obj.z, reinterpret_cast<char *>(&obj) + log );

    return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中有两个相关概念,函数指针指针函数。 1. 函数指针(Function Pointers):函数指针指向函数的指针变量。它可以用来存储和调用特定型的函数。通过函数指针,可以在运行时动态地选择要执行的函数。函数指针的声明形式为:`返回型 (*指针变量名)(参数列表)`。例如,以下是一个函数指针的示例: ```c #include <stdio.h> void display(int num) { printf("Number: %d\n", num); } int main() { void (*func_ptr)(int); // 声明一个函数指针变量 func_ptr = display; // 将函数的地址赋值给函数指针变量 func_ptr(10); // 通过函数指针调用函数 return 0; } ``` 2. 指针函数(Pointer to a Function):指针函数是一个返回指向函数的指针的函数。它返回的是函数的地址,而不是函数的返回值。指针函数的声明形式为:`返回型 (*函数名)(参数列表)`。以下是一个指针函数的示例: ```c #include <stdio.h> int add(int num1, int num2) { return num1 + num2; } int subtract(int num1, int num2) { return num1 - num2; } int (*getOperation(char op))(int, int) { if (op == '+') { return add; // 返回add函数的地址 } else { return subtract; // 返回subtract函数的地址 } } int main() { int num1 = 10, num2 = 5; char op = '+'; int (*operation)(int, int); // 声明一个指针函数变量 operation = getOperation(op); // 将指针函数的返回值(函数地址)赋值给指针函数变量 int result = operation(num1, num2); // 通过指针函数调用对应的函数 printf("Result: %d\n", result); return 0; } ``` 以上就是函数指针指针函数的基本概念和用法。通过它们,可以实现更灵活的函数调用和动态选择执行的函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值