The pointer conversion acts as a static_cast
. 5.2.9/2 says,
If the object of type [A
] is actually a subobject of an object of
type [B
], the result refers to the enclosing object of type [B
].
Otherwise, the result of the cast is undefined.
Your object is not a subobject of a B
object, so the result is undefined.
Even if you were to reinterpret_cast
, accessing the value of the object through the resulting pointer has undefined behavior because it violates strict aliasing. In the C++11 standard, 3.10/10:
If a program attempts to access the stored value of an object through
a glvalue of other than one of the following types the behavior is
undefined:
"A derived class of the dynamic type of the object that adds no data members or virtual member functions" is not in the list that follows.
Depending on what method1
actually does, it might be possible to avoid accessing the stored value of the object when calling it. But I'm not certain it's ever possible. Unless stated otherwise elsewhere in the standard I would assume for safety that calling a non-static member function inherently "accesses the stored value of the object" even if the function doesn't actually use any data members.
This is one of those awkward cases that will probably work in practice either all the time or almost all the time. But it's not guaranteed, so even if it appears to work and the emitted code looks OK, you will live in fear that some day a new optimization will break it.
Once defined, C++ classes are closed to new members, including new member functions. So your object created with new A()
has all the member functions it will ever have. Just write a non-member function -- unless A
has protected
members it will have exactly the same access to A
that your member function has. And if A
does have protected
members then there's an approved way of deriving from it, which you should use to create proper instances of B
.
If member function syntax means that much to you, then depending on the class A
you might be able to write:
B b = *a; // "copy" the object (give B a suitable ctor)
b.method1(); // act on it
*a = b; // copy it back (A needs copy assignment operator)
Obviously there are issues here that could stop it working: to begin with whether the object is copyable, also thread-safety, and whether method1
stores a pointer/reference to b
somewhere that will start to dangle as soon as b
is destroyed. In C++11 the copies could perhaps be moves for efficiency, but even so I hope you will agree that the hoops you have to jump through to use member function syntax are not worth it.