在 C++ 中,可以通过打印函数指针的地址来查看它的内存地址。对于类中的成员函数指针,打印它的地址和普通函数指针稍有不同。下面是一个示例代码,展示如何打印 funcPtr
的地址。
#include <iostream>
class Base {
public:
virtual void show(int value) { // 虚函数
std::cout << "Base class value: " << value << std::endl;
}
virtual ~Base() = default; // 虚析构函数
};
class Derived : public Base {
public:
void show(int value) override { // 重写虚函数
std::cout << "Derived class value: " << value << std::endl;
}
};
int main() {
Derived derivedObj; // 创建派生类对象
Base* basePtr = &derivedObj; // 基类指针指向派生类对象
// 获取 vtable 中成员函数的地址 (需要强制转换为合适类型)
void (Base::*funcPtr)(int) = &Base::show;
// 打印 funcPtr 的地址
std::cout << "Address of funcPtr: " << static_cast<void*>(funcPtr) << std::endl;
// 调用带参数的虚成员函数
(basePtr->*funcPtr)(10); // 输出:Derived class value: 10
return 0;
}
解释:
- 获取成员函数字段:使用
&Base::show
获取到Base
类中show
函数的地址,并将其赋值给funcPtr
。 - 打印地址:使用
std::cout
打印出funcPtr
的地址。在这里,为了避免编译器警告,我们将funcPtr
转换为void*
类型,这样可以更直观地显示其内存地址。
注意事项:
- 成员函数指针的格式通常不直接以数值形式输出,因此需要转换为其他类型(如
void*
)来进行打印。 - 不同于普通指针,成员函数指针在 C++ 中包含额外的信息以支持虚拟继承,因此如果你直接尝试以整数形式输出它,可能会遇到编译错误或未定义行为。使用静态转换是一种安全的方法。
内容由零声教学AI助手提供,问题来源于学员提问