将基础实例指针转换为派生实例指针是否合法? (该实例不是派生实例)

is it legal to cast base-instance-pointer to derived-instance-pointer? (the instance is not a derived instance)

我想以不合格的方式(为什么?宏魔法)从 class 本身之外访问 Base class 成员。该策略是在 Derived class 中执行并将指向 Base 的指针转换为指向 Derived 的指针(即使实例不是 一个Derived).

根据我的尝试,代码可以正确编译和运行:这是 标准 还是 意外 (和 UB 标准) ? coliru link

#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 对象的子对象。

请注意,cppreference page on static_cast 并未明确说明强制转换本身具有未定义的行为,但它具有,如上文所述。

我想您的代码 运行 会很好。因为它确实有 "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" 成员,其类型是真正的 Base class。函数指针调用的函数getB,不属于任何实例变量,所以不符合。