将基本实例指针强制转换为派生实例指针是否合法?(实例不是派生实例)



我想从类本身之外以非限定的方式(为什么?宏巫术(访问Base类成员。策略是在类Derived执行此操作,并将指针强制转换为指向Derived的指针Base(即使实例不是Derived(。

据我尝试,代码可以正确编译和运行:这是标准还是偶然(以及标准中的 UB(? 科里鲁链接

#include<iostream>
struct Base{
int a=3;
};
struct Derived: public Base{
int getA(){
// this scope has unqualified access to Base class members
return a;
}
};
int main(void){
Base b;
std::cerr<<((Derived*)(&b))->getA()<<std::endl;
}

如果&b指向的对象实际上不是Derived对象的子对象,则强制转换(Derived*)(&b)将等效于具有未定义行为的static_cast<Derived*>(&b)。参见当前C++标准草案的[static.cast]/11(至少自C++11以来就存在等效语言(。

因此,您的程序具有未定义的行为,因为根本没有创建任何Derived对象,并且b不是Derived对象的子对象。

请注意,static_cast上的 cppreference 页面没有明确说明强制转换本身具有未定义的行为,但如上所述,它确实具有。

我想你的代码会运行得很好。 因为它确实具有"a"成员变量。

struct Derived: public Base{
int c;
int getA(){
// this scope has unqualified access to Base class members
return a;
}
int getC(){            
return c;
}
};
int main(void){
Base b;
std::cerr<<((Derived*)(&b))->getC()<<std::endl;
} 

上面的代码将运行错误,因为变量"b"中没有"c"成员,其类型是真正的基类。函数 getB 由函数指针调用,它不属于任何实例变量,因此不会受到影响。

最新更新