Assuming I have a base class A and publicly derived class B, how should I assign A object to the A base class subobject of B?
class A {...};
class B : public A {...};
A a(..);
B b(..);
static_cast<A&>(b) = a; ???
Is that doable without writing assignement operator for B? Are there any potential problems with casting b to A&? Is that standard conformant?
Writing another answer to demonstrate why and how assign a base class object to a derived class object.
struct TimeMachineThing_Data {
..
..
};
class TimeMachineThing : private TimeMachineThing_Data
{
static std::stack<TimeMachineThing_Data> m_stateHistory;
void SaveState() {
m_stateHistory.push_back( static_cast<TimeMachineThing_Data&>(*this) );
}
void RestoreState() {
static_cast<TimeMachineThing_Data&>(*this) = m_stateHistory.front();
m_stateHistory.pop_front();
}
};
It's very useful and fully legitimate.
(Here is private inheritance, so only internally TimeMachineThing IS-A TimeMachinetime_Data)
Another one.
struct StructWithHundresField {
string title;
string author;
...
StructWithHundresField() {
...
}
};
class EasyResetClass : public StructWithHundresField {
int not_reset_this_attriute;
public:
void ResetToInitialStateAtAnyTime() {
static_cast<StructWithHundresField&>(*this) = StructWithHundresField();
}
}
That's a really bad idea. A is the base, B is a derived type. By casting B to an A, you are now using A's assignment operator, which isn't going to touch any of the extra derived data. At the end of that assignment, b
is still considered to be of type B
, even though it now contains an A
. This is the opposite of the way inheritance is meant to be used.
Changing the line to b = reinterpret_cast<B&>(a);
would be even worse. Then you would be pretending that a
is a B
when it's not, and you be reading invalid memory.
If you truly want to do this kind of assignment, you want:
class B : public A {
B& operator= (const A& a) { ... }
};
Then you can write a function to copy the information from the A
, and somehow deal with the extra information in the derived type B
, plus this would allow you to simply write:
b = a;
Think for a minute about whether this is a good idea. Remember that if you have B subclassing A, then every B is an A but not every A is a B. For example, every dog is a mammal, but not every mammal is a dog. If you have a concrete B object, trying to set it to an A object isn't mathematically well-defined in most cases. Moreover, in the world of C++, because you B object is statically typed as a B, you can never assign it an object of type A in a way that will make it stop being a B. At best, you're going to overwrite just the A portion of the B object without changing any of the B-specific parts.
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