我目前正在处理一个遗留的C++代码库。在这个代码库中,对象的指针被转换为void指针,然后存储在一个C库中。 考虑以下代码:
class interface {
public:
virtual void foo() {
std::cout << "Interface" << std::endl;}
virtual ~interface(){};
};
class debug_interface: public interface {
public:
virtual void foo() {
std::cout << "Debug Interface" << std::endl;}
};
对象interface
和debug_interface
在堆上分配,地址存储在一个无类型指针中。在某些时候,这些指针被检索并转换回基类interface
,然后调用虚函数。请参见。
int main(int argc, char *argv[]){
void *handle = reinterpret_cast<void*>(new interface());
void *debug_handle = reinterpret_cast<void*>(new debug_interface());
//void *handle = new interface();
//void *debug_handle = new debug_interface();
interface *foo1 = reinterpret_cast<interface*>(handle);
interface *foo2 = reinterpret_cast<interface*>(debug_handle);
//interface *foo1 = static_cast<interface*>(handle);
//interface *foo2 = static_cast<interface*>(debug_handle);
foo1->foo();
foo2->foo();
return 0;
}
首先,我不理解为什么要使用reinterpret_cast。据我所知,对象指针可以隐式转换为void*指针。此外,为了使类型转换明确,使用static_cast就足够了,是这样吗?
更重要的问题是:将指针debug_handle强制转换为interface*(而不是debug_interface*)并调用虚函数真的安全吗?根据C++标准(5.2.10),这是未定义行为。
“指向T1”的值v可以显式转换为指向不同对象类型的值“指向cv T2”的值。如果T1和T2都是标准布局类型(3.9),并且T2的对齐要求不比T1严格,当类型为“指向T1”的prvalue v转换为类型“指向T2”时,结果为static_cast(static_cast(v))。将类型为“指向T1”的prvalue转换为类型“指向T2”(其中T1和T2都是对象类型,并且T2的对齐要求不比T1严格),然后再转回其原始类型,将得到原始指针值。任何其他此类指针转换的结果是未指定的。
从handle转换为foo1应该没问题,但我是否可以再次使用static_cast呢?
编辑:我的示例源代码是错误的。debug_interface是interface的派生类。