【问题标题】:why the result is not in my expectation?为什么结果出乎我的意料?
【发布时间】:2011-11-24 23:38:30
【问题描述】:
#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 函数。我不知道为什么,请帮助我

【问题讨论】:

  • vs2010 ,你的意思是可能跟编译器有关系?
  • 是的,成员变量/方法在内存中的排序方式取决于编译器。
  • 您所做的几乎所有事情都会导致未定义的行为,所以我不确定您为什么期望发生任何特别的事情。

标签: c++ function-pointers virtual-functions


【解决方案1】:

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

不能。

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

如果将 typedef 更改为:

typedef void (*pFun)(A*);

和调用

pFunc(&obj);

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

【讨论】:

    【解决方案2】:

    将 1 添加到 int* 仅在遍历 int[] 的情况下具有定义的行为。

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

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

    另外,如果你按照这种方式获取函数地址,将其作为静态方法(不带对象)调用,只会让你头疼。

    【讨论】:

      【解决方案3】:

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

      我建议您对指针和 C++ 类有一个基本的误解,必须先纠正这些误解,然后才能安全地管理这些。大多数人不需要函数指针,几乎没有人需要方法指针。

      【讨论】:

      • 想你给我的建议,我会记住的
      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2022-08-02
        • 2014-04-02
        • 1970-01-01
        • 2020-09-26
        • 2021-03-25
        • 1970-01-01
        • 2016-09-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多