Consider this example, where the base class has some data members, while derived one only provides an additional method:
struct TestBase
{
int x;
TestBase() : x(5) {}
};
struct TestDerived : public TestBase
{
void myMethod()
{
x=8;
}
};
int main()
{
TestBase b;
TestDerived& d=static_cast<TestDerived&>(b);
d.myMethod();
}
This is downcasting to wrong type, so AFAIU it has undefined behavior. But are there maybe some exceptions to such cases as this, where the derived class' layout is identical to that of base class?
From the standard (emphasis mine):
§5.2.9 Static cast [expr.static.cast] ...
(2) An lvalue of type “cv1 B,” where B is a class type, can be cast to type “reference to cv2 D,” where D is a class derived from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists, cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is neither a virtual base class of D nor a base class of a virtual base class of D. The result has type “cv2 D.” An xvalue of type “cv1 B”may be cast to type “rvalue reference to cv2 D” with the same constraints as for an lvalue of type “cv1 B.” If the object of type “cv1 B” is actually a subobject of an object of type D, the result refers to the enclosing object of type D. Otherwise, the behavior is undefined.
My first guess was that the cast should be valid in this case, because I got confused by the term subobject.
Now (thanks to @T.C. and @M.M), it is obvious that the behavior is undefined in this case.
The cast would be valid in the following example:
int main()
{
TestDerived d;
TestBase &br = d; // reference to a subobject of d
TestDerived &dr = static_cast<TestDerived&>(br); // reference to the original d object
d.myMethod();
}
Here, an object of class TestDerived
(d
) will have a subobject of class TestBase
(br
is a reference to this object).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With