在基类不可移动时,有意义的\适合标记派生类是可移动的吗?
在基类不可移动时,有意义的\适合标记派生类是可移动的吗?
我知道这种 不一致是在C ++中是合法的 ,但是在实践中 有意义 ?
一般而言 ,i 是否应该保持 保持这样的一致性?
这种情况 :当我打算将派生类别标记为不可移动且不可仿制时,我是否应该将基础类标记为不可移动且不可移动, 也?
我做了几项测试以清楚地表明。
这是第一个示例。由于基类是不可复制的且不可移动的,因此派生的类实际上是不可移动的,它具有移动构造函数,这是我的期望。提示:下面的代码段未编译。
#include <memory>
#include <string>
#include <iostream>
class Base {
public:
Base(){}
Base(const Base&) = delete;
Base(Base&&) = delete;
Base& operator=(const Base&) = delete;
Base& operator=(Base&&) = delete;
};
class Derived:public Base
{
public:
Derived(){}
Derived(const Derived&) = default;
Derived(Derived&&) = default;
Derived& operator=(const Derived&) = default;
Derived& operator=(Derived&&) = default;
};
int main()
{
Derived derived;
Derived derived1{std::move(derived)};
}
这是第二个示例。基类是可复制的,不可移动的,但是派生类是可移动的同样在我的期望中。提示:下面的代码段效果很好。
#include <memory>
#include <string>
#include <iostream>
class Base {
public:
Base(){}
Base(const Base&) = default;
Base(Base&&) = delete;
Base& operator=(const Base&) = default;
Base& operator=(Base&&) = delete;
};
class Derived:public Base
{
public:
Derived(){}
Derived(const Derived&) = default;
Derived(Derived&&) = default;
Derived& operator=(const Derived&) = default;
Derived& operator=(Derived&&) = default;
};
int main()
{
Derived derived;
Derived derived1{std::move(derived)};
}
更新 :
感谢@nightlord,他发现代码上面的摘要不使用clang
编译,这确实是我的期望。
Is it meaningful\suitable to mark the derived class as movable while the base class is non-moveable?
I know this kind of inconsistency is legal in C++, but is it meaningful\suitable in practise?
In general, should I sedulously keep such consistency?
What about this case:when I intend to mark the derivd class as non-moveable and non-copyable, should I mark the base class as non-moveable and non-copyable, too?
I did several tests to make it clear.
Here is the first example. Since the base class is non-copyable and non-moveable, the derived class is non-moveable in fact through it has a move constructor, which is in my expectation. Tips: the code snippet below does not compile.
#include <memory>
#include <string>
#include <iostream>
class Base {
public:
Base(){}
Base(const Base&) = delete;
Base(Base&&) = delete;
Base& operator=(const Base&) = delete;
Base& operator=(Base&&) = delete;
};
class Derived:public Base
{
public:
Derived(){}
Derived(const Derived&) = default;
Derived(Derived&&) = default;
Derived& operator=(const Derived&) = default;
Derived& operator=(Derived&&) = default;
};
int main()
{
Derived derived;
Derived derived1{std::move(derived)};
}
Here is the second example. The base class is copyable and non-moveable, but the derived class is moveable in fact since it will invoke the copy constructor of the base class instead of the move constuctor of base class when the move constructor of the derived class is called, which is also in my expectation.Tips: the code snippet below works well.
#include <memory>
#include <string>
#include <iostream>
class Base {
public:
Base(){}
Base(const Base&) = default;
Base(Base&&) = delete;
Base& operator=(const Base&) = default;
Base& operator=(Base&&) = delete;
};
class Derived:public Base
{
public:
Derived(){}
Derived(const Derived&) = default;
Derived(Derived&&) = default;
Derived& operator=(const Derived&) = default;
Derived& operator=(Derived&&) = default;
};
int main()
{
Derived derived;
Derived derived1{std::move(derived)};
}
UPDATED:
Thanks to @Nightlord, he found that the code snippet above does not compile with Clang
, which is really out of my expectation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,我认为您应该保持一致性。
为了使派生的类可移动,而基类不可移动,基类无法容纳任何数据成员,否则,该运动将未完成。
在您的类不容纳任何数据成员的情况下,您可能将其用作接口。移动构造器不适用于这种情况,因为客户端仅识别接口(基类)而不是混凝土类(派生类)。
Yes, I think you should keep the consistency.
To make a derived class movable while the base class is not, the base class cannot hold any data member, otherwise, the movement is not completed.
In the case your class does not hold any data member, you might be using it as an interface. Moving constructor does not work with such a case since the client only recognizes the interface (the base class) rather than the concrete class (the derived class).