这是我的代码。
class IService {
};
class X_Service {
public:
void service1() {
std::cout<< "Service1 Running..."<<std::endl;
}
};
int main() {
IService service;
auto func = reinterpret_cast<void (IService::*)()>(&X_Service::service1);
(service.*(func))();
return 0;
}
我不知道这是如何工作的。我没有继承IService,也没有创建X_Service对象,但是它可以工作。有人可以解释吗?
您可以通过多种方式打破语言规则,仍然编写可编译和运行的代码。通过在此处使用reinterpret_cast
并进行无效的转换,您已经破坏了语言规则,并且您的程序具有未定义的行为。
这意味着它似乎可以工作,可能崩溃或只能做与您想要的完全不同的事情。
在您的情况下,它似乎可以正常工作,但是它仍然是UB,并且代码无效。
成员函数只是一个函数,除了局部变量和参数外,还具有一块存储类对象地址的内存。该内存保留使用this
关键字时要访问的地址。
如果您在错误的对象或nullptr上调用成员函数,则基本上只是使this
指针指向无效的对象。
您的功能无法访问this
,这就是您的程序不会崩溃的原因。
也就是说,这仍然是未定义的行为,任何事情都可能发生。
reinterpret_cast
指向不同类型的函数或成员函数指针时,除非您先将其强制转换回其原始类型并通过该指针进行调用,否则将永远不允许调用此指针。违反此规则将导致undefined behavior。这意味着您失去了任何语言保证,即程序将以任何特定方式运行,而没有来自特定编译器的其他保证。
reinterpret_cast
通常很危险,因为它完全绕过了类型系统。如果使用它,则需要始终通过查看语言规则来验证自己,是否明确定义了强制类型转换和使用结果的方式。 reinterpret_cast
告诉编译器您知道自己在做什么,并且即使结果是无意义的,也不希望出现任何警告或错误。