指向成员函数的地址是啥,没有虚拟也没有继承
Posted
技术标签:
【中文标题】指向成员函数的地址是啥,没有虚拟也没有继承【英文标题】:what is the address of pointer-to-member functions, no virtual and no inherit指向成员函数的地址是什么,没有虚拟也没有继承 【发布时间】:2012-08-10 02:43:33 【问题描述】:我写了一些测试代码,找出成员函数的地址。但结果让我很困惑。代码是
#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 为 nil?
【问题讨论】:
你使用编译器优化吗? Pointers to member functions are very strange animals. 【参考方案1】:指向成员的指针不是常规指针,您可以通过打印成员指针的大小和常规指针的大小来测试它。您拥有的代码表现出未定义的行为,但如果您想对结果进行简单解释,printf
采用可变数量的参数,这是通过以某种先入为主的顺序将参数推送到堆栈并添加一些额外信息来实现的调用中的参数数量是多少。
在您的情况下,指向成员的函数按原样被推送(通常是常规指针大小的两倍),然后printf
正在读取堆栈并将那里的位解释为常规指针。我的猜测(你必须阅读编译器/平台文档来验证这一点)是你只打印前两个参数,内容用逗号分隔。
一个更好的方法是创建一个指向成员函数的指针和一个适当大小的 char 数组的联合,用指向成员的指针对其进行初始化并通过数组打印十六进制值。
【讨论】:
【参考方案2】:为什么 pf2 和 pf4 为 nil?
因为显示的代码具有未定义的行为。指向成员函数are not pointers 的指针(是的,是的,我知道这是不好的命名;C++ 就是这样),但 printf 格式字符串需要指针。
【讨论】:
以上是关于指向成员函数的地址是啥,没有虚拟也没有继承的主要内容,如果未能解决你的问题,请参考以下文章