通过移动派生的一个来构造基 class
Constructing base class by moving derived one
我有这个简化的代码示例:
class Base {
Base() = default;
Base(const Base& src) {
// construct by copying src etc. - ok, legal even if src points to Derived object
}
Base(Base&& src) {
// construct by moving src - stealing its resources, ok, it was invented for this,
// but.. what if src points to Derived object?
}
};
class Derived : public Base {
};
void foo() {
Derived derived;
Base base_by_copy_constructor(derived); // legal, derived cannot be touched so nothing will be wrong
Base base_by_move(std::move(derived)); // uu? what's gonna happen, part of derived object (Base class) was moved..
}
这样的行为合适吗?这可能会导致奇怪的问题,因为 Base 部分 od Derived 对象实际上是 'deinitialized'。
所以.. 我们应该避免从具有移动运算符的 class 派生,还是让我们的 Derived class 抵抗 'moving' 它的基础部分?
(当然 - 这只是示例,classes 没有数据,移动运算符不做任何事情,所以这里不会出错。我问的是这样一个真实世界的例子.. 情况 :) )
他们的切片没有问题,这可以明确和intensionnaly完成。
尽管如此,在一般情况下进行 OO 编程时,只有一条规则需要遵循:不要让对象(或组件)外部的任何实体有机会破坏不变量.
因此,如果调用基 class 的成员或构造函数可能会破坏派生的 class 与其基之间建立的不变量,那么基必须是私有的。 (你仍然可以带来 public 不破坏不变量的基础成员 using base::member
)
我有这个简化的代码示例:
class Base {
Base() = default;
Base(const Base& src) {
// construct by copying src etc. - ok, legal even if src points to Derived object
}
Base(Base&& src) {
// construct by moving src - stealing its resources, ok, it was invented for this,
// but.. what if src points to Derived object?
}
};
class Derived : public Base {
};
void foo() {
Derived derived;
Base base_by_copy_constructor(derived); // legal, derived cannot be touched so nothing will be wrong
Base base_by_move(std::move(derived)); // uu? what's gonna happen, part of derived object (Base class) was moved..
}
这样的行为合适吗?这可能会导致奇怪的问题,因为 Base 部分 od Derived 对象实际上是 'deinitialized'。 所以.. 我们应该避免从具有移动运算符的 class 派生,还是让我们的 Derived class 抵抗 'moving' 它的基础部分?
(当然 - 这只是示例,classes 没有数据,移动运算符不做任何事情,所以这里不会出错。我问的是这样一个真实世界的例子.. 情况 :) )
他们的切片没有问题,这可以明确和intensionnaly完成。
尽管如此,在一般情况下进行 OO 编程时,只有一条规则需要遵循:不要让对象(或组件)外部的任何实体有机会破坏不变量.
因此,如果调用基 class 的成员或构造函数可能会破坏派生的 class 与其基之间建立的不变量,那么基必须是私有的。 (你仍然可以带来 public 不破坏不变量的基础成员 using base::member
)