gpt4 book ai didi

c++ - Visual C++ 编译器如何将 this ptr 传递给被调用函数?

转载 作者:太空狗 更新时间:2023-10-29 21:06:47 28 4
gpt4 key购买 nike

我正在使用 Eckel 的“Thinking in C++”学习 C++。它声明如下:

  • 如果一个类包含虚方法,则为该类创建一个虚函数表等。粗略地解释了函数表的工作原理。 (我知道 vtable 不是强制性的,但 Visual C++ 创建了一个。)
  • 调用对象作为参数传递给被调用函数。 (对于 Visual C++(或任何编译器),这可能不是真的。)我试图找出 VC++ 如何将调用对象传递给函数。

为了在 Visual C++ 中测试这两点,我创建了以下类(使用 Visual Studio 2010,WinXP Home 32 位):

ByteExaminer.h:

#pragma once
class ByteExaminer
{
public:
short b[2];
ByteExaminer(void);
virtual void f() const;
virtual void g() const;
void bruteFG();
};

ByteExaminer.cpp:

#include "StdAfx.h"
#include "ByteExaminer.h"

using namespace std;

ByteExaminer::ByteExaminer(void)
{
b[0] = 25;
b[1] = 26;
}

void ByteExaminer::f(void) const
{
cout << "virtual f(); b[0]: " << hex << b[0] << endl;
}

void ByteExaminer::g(void) const
{
cout << "virtual g(); b[1]: " << hex << b[1] << endl;
}

void ByteExaminer::bruteFG(void)
{
int *mem = reinterpret_cast<int*>(this);
void (*fg[])(ByteExaminer*) = { (void (*)(ByteExaminer*))(*((int *)*mem)), (void (*)(ByteExaminer*))(*((int *)(*mem + 4))) };
fg[0](this);
fg[1](this);
}

bruteFG() 中 vtable 的导航有效 - 当我调用 fg[0](this) 时,f() 是叫。然而,不起作用的是将 this 传递给函数 - 这意味着 this->b[0] 未正确打印(而是出现垃圾。我我真的很幸运这不会产生段错误)。

所以实际输出为

ByteExaminer be;
be.bruteFG();

是:

virtual f(); b[0]: 1307
virtual g(); b[1]: 0

那么我应该如何进行才能得到正确的结果呢? this 指针如何传递给 VC++ 中的函数?

(注意:我不会认真地用这种方式编程,永远不会。这是“为了好玩”;或者为了学习经验。所以不要试图将我转变为正确的 C++ 风格 :) )

最佳答案

Visual Studio 中的成员函数有一个特殊的调用约定,__thiscall,其中this 在一个特殊的寄存器中传递。哪一个,我不记得了,但 MSDN 会说。如果您想调用 vtable 中的函数指针,则必须使用汇编程序。

当然,您的代码表现出大量未定义的行为 - 使用 charunsigned char 指针为对象设置别名是唯一可行的,绝对不能使用 int 指针 - 甚至忽略整个 vtable 假设。

关于c++ - Visual C++ 编译器如何将 this ptr 传递给被调用函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6802395/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com