假设我有一个基类 A 和公共派生类 B,我应该如何将 A 对象分配给 B 的 A 基类子对象?
class A {...};
class B : public A {...};
A a(..);
B b(..);
static_cast<A&>(b) = a; ???
Run Code Online (Sandbox Code Playgroud)
不为 B 编写赋值运算符是否可行?将 b 转换为 A& 是否有任何潜在问题?那个标准符合吗?
编写另一个答案来演示为什么以及如何将基类对象分配给派生类对象。
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();
}
};
Run Code Online (Sandbox Code Playgroud)
它非常有用且完全合法。
(这里是私有继承,所以只有内部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();
}
}
Run Code Online (Sandbox Code Playgroud)
这真是个坏主意。A 是基类,B 是派生类型。通过将 B 强制转换为 A,您现在正在使用 A 的赋值运算符,它不会触及任何额外的派生数据。在该赋值结束时,b仍然被认为是类型B,即使它现在包含一个A. 这与继承的使用方式相反。
将线路更改为b = reinterpret_cast<B&>(a);会更糟。然后你会假装这a是一个B当它不是,你正在阅读无效的记忆。
如果你真的想做这种任务,你需要:
class B : public A {
B& operator= (const A& a) { ... }
};
Run Code Online (Sandbox Code Playgroud)
然后,您可以编写一个函数来复制 中的信息A,并以某种方式处理派生类型中的额外信息B,此外,您还可以简单地编写:
b = a;
Run Code Online (Sandbox Code Playgroud)