为什么结果不在我的期望中

why the result is not in my expectation?

本文关键字:我的 期望中 结果 为什么      更新时间:2023-10-16
#include <iostream>
using namespace std;
typedef void (*pFun)(void);
class A
{
private:    
    int a; 
    int b;
    virtual void outPrint()
    {
        cout << b << endl;
    }
 public:
    A()
    {
        a = 3;      
        b = 4;
    }
};
int main() 
{   
    A obj;
    cout << *((int*)(&obj)+1) << endl;
    pFun pFunc;     
    pFunc = (pFun)*((int*)*(int*)(&obj));   
    pFunc();
    system("pause");
    return 0; 
}

当我调用 pFunc(( 时,我认为结果应该是 4,但实际上它是一个随机数。我调试了程序,发现 pFunc 指向 outPrint 函数。我不知道为什么,请帮帮我

似乎

您假设对象obj的地址可以解释为您定义的类型的函数的地址。

不能。

我不完全确定你为什么会有这样的假设。您可能正在假设有关动态调度的内部实现。但请注意:您希望调用A::outPrint接受 1 个参数(this,未明确定义(,而您的 typedef 假定没有参数。因此,即使地址转换工作正常,并且您获得的地址是成员函数的地址(这首先是一个延伸(,您的调用也是不正确的。

如果将 typedef 更改为:

typedef void (*pFun)(A*);

和呼吁

pFunc(&obj);

这也许可行。然而,据我所知,每个规范的行为是未定义的。

int*中添加 1 仅在遍历int[]的情况下定义了行为。

在所有其他情况下,都没有定义应该发生什么。它是定义的实现,因为没有定义成员的最终内存位置。

尝试以不利用编译器详细信息而是利用标准的方式解决问题。

此外,如果您以这种方式获得函数地址,将其作为静态方法(没有对象(调用,只会给您带来一些麻烦。

我不太确定你到底想做什么。看起来您正在尝试直接操作指针以获取方法的地址,但由于大约 6 个不同的原因,这是一个非常糟糕的主意。可以获取指向类方法的指针,但它未绑定到对象,因此需要小心。

我建议你对指针和C++类有一个根本性的误解,在你安全地管理任何这些之前,必须纠正这些误解。大多数人不需要函数指针,几乎没有人需要方法指针。

您依赖于各种"未定义的行为",因此结果取决于您运行的编译器和平台。

(int*(&

obj+1(最好写((int*(&obj(+1以避免误解(不一定是b成员。成员之间可能有填充,&obj 可能与 obj &(obj.a)多态对象不同(因此它可能在其顶部有一个 vtable 指针(。

如果

在这种情况下,*(int*)&obj vtable 地址被视为 int.将其转换为 int*(假设 int 和指针具有相同的大小(,它指向第一个 vtable 条目(很可能是 outPrint 的地址(,因此是"随机数"。