派生 class returns 已分配基础 class 实例
Derived class returns allocated base class instance
下面的C++是合法的吗?
derived class 正在分配 base class 并将其转换为 derived。
显然,如果派生 (C) 有成员,任何人通过返回的指针访问成员都会失败。但即使没有派生成员——这是合法的吗? UB ?
struct B { int a; };
struct C : B {
static C* get() {
return static_cast<C*>(new B);
}
enum { X, Y,};
};
int main(){
C* c = C::get();
return c->X;
}
是UB。标准摘录(强调我的):
8.2.9 Static cast - bullet 11
A prvalue of type “pointer to cv1 B”, where B is a class type, can be converted to a prvalue of type “pointer to cv2 D”, where D is a class derived from B, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If B is a virtual base class of D or a base class of a virtual base class of D, or if no valid standard conversion from “pointer to D” to “pointer to B” exists ([conv.ptr]), the program is ill-formed. The null pointer value is converted to the null pointer value of the destination type. If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined.
下面的C++是合法的吗? derived class 正在分配 base class 并将其转换为 derived。 显然,如果派生 (C) 有成员,任何人通过返回的指针访问成员都会失败。但即使没有派生成员——这是合法的吗? UB ?
struct B { int a; };
struct C : B {
static C* get() {
return static_cast<C*>(new B);
}
enum { X, Y,};
};
int main(){
C* c = C::get();
return c->X;
}
是UB。标准摘录(强调我的):
8.2.9 Static cast - bullet 11
A prvalue of type “pointer to cv1 B”, where B is a class type, can be converted to a prvalue of type “pointer to cv2 D”, where D is a class derived from B, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If B is a virtual base class of D or a base class of a virtual base class of D, or if no valid standard conversion from “pointer to D” to “pointer to B” exists ([conv.ptr]), the program is ill-formed. The null pointer value is converted to the null pointer value of the destination type. If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined.