2

我写了一些测试代码,找出成员函数的地址。但结果让我很困惑。代码是

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

class A
{
public:
        A(char _a, char _b, char _c, char _t):a(_a), b(_b), c(_c), t(_t){}

private:
        char t;
        char a;
public:
        char b;
        char c;
        void test1(){std::cout << a << std::endl;}
        void test2(){std::cout << b << std::endl;}
        void test3(){std::cout << c << std::endl;}
        void test4(){std::cout << t << std::endl;}

        static void print(){

                char A::*pa = &A::a;
                char A::*pb = &A::b;
                char A::*pc = &A::c;
                char A::*pt = &A::t;
                printf("data member : %p, %p, %p, %p\n", pa, pb, pc, pt);

                void (A::*pf1)() = &A::test3;
                void (A::*pf2)() = &A::test2;
                void (A::*pf3)() = &A::test3;
                void (A::*pf4)() = &A::test2;
                printf("function member : %p, %p, %p, %p\n", pf1, pf2, pf3, pf4 );
        }
};

int main()
{
        A::print();

    //system("pause");//need on Dev-c++
        return 0;
}

我用g++在ubuntu上运行这段代码,用Dev-C++在Windos上运行,结果是一样的

data member : 0x1, 0x2, 0x3, (nil)
function member : 0x8048780, (nil), 0x804874e, (nil)

为什么 pf2 和 pf4 为零?

4

2 回答 2

3

指向成员的指针不是常规指针,您可以通过打印指向成员的指针的大小和常规指针的大小来测试它。您拥有的代码表现出未定义的行为,但如果您想要对结果进行简单解释,printf则采用可变数量的参数,这是通过以某种先入为主的顺序将参数推送到堆栈并添加一些关于数量的额外信息来实现的调用中的参数是。

在您的情况下,指向成员函数的指针按原样被推送(通常是常规指针大小的两倍),然后printf读取堆栈并将那里的位解释为常规指针。我的猜测(你必须阅读编译器/平台文档来验证这一点)是你只打印前两个参数,内容用逗号分隔。

一个稍微好一点的方法是创建一个指向成员函数的指针和一个适当大小的 char 数组的联合,用指向成员的指针初始化它并通过数组打印十六进制值。

于 2012-08-10T03:08:20.383 回答
2

为什么 pf2 和 pf4 为零?

因为显示的代码具有未定义的行为。指向成员函数的指针不是指针(是的,是的,我知道这是不好的命名;C++ 就是这样),但 printf 格式字符串需要指针。

于 2012-08-10T02:54:28.120 回答