我有一个带有虚拟默认析构函数的基
State
接口类。
class State {
public:
virtual void event() = 0;
virtual ~State() = default; // relevant part
virtual void onCreate() {}
virtual void onDestroy() {}
virtual void onActivate() {}
virtual void onDeactivate() {}
};
然后是一些继承它的类:
class GameState : public State {
public:
void event() override;
// ...
};
class MenuState : public State {
public:
void event() override;
// ...
};
如果没有复制操作或用户定义了“析构函数”,则编译器会生成默认的移动操作。
如果用户没有定义移动操作,编译器会生成默认的复制操作。通过声明虚拟默认析构函数我已经有效地删除了默认移动操作,我是否正确?
MenuState menuState;
State state = menuState; // be aware that this State object is not a MenuState any more
如果你的
State
类是抽象的(例如 onActivate()
是纯虚拟的),上面的方法就没有任何意义,因为
State
实例是不允许的。
但即使没有,当您将任何
MenuState
成员放入 State
对象时,它们也会被切片。如果基类的实例本身没有多大意义,则应该删除复制和移动构造函数以及赋值运算符。
对于派生(具体)类,复制或移动可能更有意义。在这种情况下,在基类中拥有
protected
复制构造函数和赋值运算符会很有用。因此,您无法实例化基类本身,但您的派生类可以使用它。
MenuState menuState;
MenuState copy = menuState; // might be useful
但是,此类层次结构通常与指针一起使用(如 std::unique_ptr
或 std::shared_ptr
)。那么
virtual
clone()
方法有时会更有用。
auto state = std::make_unique<MenuState>();
std::unique_ptr<State> copy = state->clone();
在内部,这个 clone()
方法可能会使用复制构造函数,它可以是 public
(如果你的派生类不是
final
,请小心切片)或
protected
(如果你想确保只有使用
clone()
方法)。