how to assign base class object to a derived class object?

徘徊边缘 提交于 2020-12-31 02:39:22

问题


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?


回答1:


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();
  }
}



回答2:


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;



回答3:


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.




回答4:


In C++ (as with other OOP languages) inheritance establish Is-A relationship.

That is, if B publicly inherit A, B = A.

You always can cast B instance to A reference without any worry.




回答5:


I would say you need an assignment operator that specifically copies an A object to a B object.

In general, it's a good idea to have one any way when copying objects of the same type. But objects of different types make it even more important.




回答6:


Everyone should know assignment is a covariant binary operator and therefore cannot work correctly with virtual functions. This is true for most binary operators, but assignment is special because it is part of the C++ language.

If you are using OO, your objects should be uncopyable and always represented by pointers. Uniqueness of object identity is the heart of OO: objects are not values, they have a unique value (their address).

If you are playing with values you should be using the appropriate concepts: functional programming (FP). That's closures (applicative objects), switches, templates, variants, and other stuff.

Try to get a solid understanding of each before mixing them. In general FP subsumes OO so is the general methodology: OO is a special case that in special circumstances delivers safe dynamic dispatch. OO dispatch is linear which means it handles an unbounded set of subtypes but it also applies only to properties (functions with one variant argument, namely the object) and can't work for anything higher order (functions with more than one variant argument). Assignment is just another 2-ary function, hence, it can't be dispatched with virtual functions.



来源:https://stackoverflow.com/questions/4575249/how-to-assign-base-class-object-to-a-derived-class-object

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!