如何将基类对象分配给派生类对象?

新手上路,请多包涵

假设我有一个基类 A 和公共派生类 B,我应该如何将 A 对象分配给 B 的 A 基类子对象?

 class A {...};
class B : public A {...};
A a(..);
B b(..);
static_cast<A&>(b) = a; ???

如果不为 B 编写赋值运算符,这是否可行?将 b 转换为 A& 是否有任何潜在问题?这个标准符合吗?

原文由 andriej 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 581
2 个回答

编写另一个答案来演示为什么以及如何将基类对象分配给派生类对象。

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

它非常有用且完全合法。

(这里是私有继承,所以只有内部TimeMachineThing IS-A TimeMachinetime_Data)


另一个。

 struct StructWithHundresField {
  string title;
  string author;
  ...

  StructWithHundresField() {
    ...
  }
};

class EasyResetClass : public StructWithHundresField {
  int not_reset_this_attriute;
public:
  void ResetToInitialStateAtAnyTime() {
    static_cast<StructWithHundresField&>(*this) = StructWithHundresField();
  }
}

原文由 9dan 发布,翻译遵循 CC BY-SA 2.5 许可协议

这真是个坏主意。 A 是基类,B 是派生类型。通过将 B 转换为 A,您现在正在使用 A 的赋值运算符,它不会触及任何额外的派生数据。在该分配结束时, b 仍然被认为是 B 类型,即使它现在包含一个 A 。这与使用继承的方式相反。

将行更改为 b = reinterpret_cast<B&>(a); 会更糟。然后你会假装 aB 而不是,你正在读取无效内存。

如果你真的想做这样的任务,你想要:

 class B : public A {
    B& operator= (const A& a) { ... }
};

然后,您可以编写一个函数来复制 A 中的信息,并以某种方式处理派生类型 B 中的额外信息,另外这将允许您简单地编写:

 b = a;

原文由 Tim 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题