基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
Defaulted destructor in base class disable move constructor in child class if there is a member
为什么Base1
中的默认(用户声明(析构函数阻止Child1
类中生成移动构造函数/运算符,但是当我将成员data
从基(Base2
(移动到子(Child2
(类时,一切正常?
struct Data {
Data() {}
Data(Data&&) noexcept { cout << "Move constructor" << endl; }
Data& operator=(Data&&) noexcept {
cout << "Move assign" << endl;
return *this;
}
vector<int> vec;
};
struct Base1 {
virtual void fun() { cout << "Base1::fun" << endl; }
virtual ~Base1() = default;
Data data;
};
struct Child1 : public Base1 {
void fun() override { cout << "Child1::fun" << endl; }
};
struct Base2 {
virtual void fun() { cout << "Base2::fun" << endl; }
virtual ~Base2() = default;
};
struct Child2 : public Base2 {
void fun() override { cout << "Child2::fun" << endl; }
Data data;
};
int main() {
Child1 c1;
auto obj1 = std::move(c1); // error
Child2 c2;
auto obj2 = std::move(c2);
}
我目前的理解是,当我在Base(BaseDel
(中将析构函数声明为"default
"时,移动构造函数在Base(BaseDel
(和子(ChildDel
(类中应该是"deleted
"。这是对的吗?我认为会员位置应该无关紧要。如果我这样做很明确,我会收到预期的错误:
struct BaseDel {
BaseDel() {}
virtual void fun() { cout << "BaseDel::fun" << endl; }
BaseDel(BaseDel&& st) = delete;
virtual ~BaseDel() = default;
};
struct ChildDel : public BaseDel {
ChildDel() {}
void fun() override { cout << "ChildDel::fun" << endl; }
Data data;
};
int main() {
ChildDel cd;
auto objd = std::move(cd); // OK, expected error
}
隐式移动构造函数不会(仅(被删除,当您拥有用户声明的析构函数时,它不会首先声明,就像Base1
和Base2
一样。
因此,移动构造函数永远不能在重载分辨率中考虑,因此auto obj1 = std::move(c1);
虽然它可以调用Child1
的移动构造函数,但需要回退到Base1
子对象的复制构造。
Base1
和Child1
的隐式声明的复制构造函数都定义为已删除,因为Data
的隐式声明的复制构造函数被定义为已删除,Data
因为它具有用户定义的移动构造函数。因此,auto obj1 = std::move(c1);
将失败,并显示删除隐式声明的复制构造函数的错误。
对于Base2
,复制构造函数未定义为已删除,因为它没有Data
成员,因此auto obj2 = std::move(c2);
将调用Child2
的移动构造函数(它也使用Data
的移动构造函数(,但对Base2
子对象使用复制构造函数。
相关文章:
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 如果基类包含双指针成员,则派生类的构造函数
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 如果存在从"双精度"到"T"的转换,则禁用构造函数
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如果这不是类的"复制构造函数",是否可以移动对象?
- 如果构造函数和析构函数可以获取和显示(打印)数据,为什么我们需要 getter 和 setter?
- 如果构造函数被显式默认或删除,为什么聚合初始化自 C++20 以来不再起作用
- 如果构造函数从调用到 std::make_shared 崩溃,GDB 是否可以显示崩溃的详细信息
- 如果构造函数中存在错误,请停止进程
- 如果构造函数是显式定义的,那么初始化类成员是强制性的吗
- 如果构造函数抛出异常,如何删除对象
- 如果构造函数正在初始化,我如何初始化对象的数组??C++
- 如果构造函数抛出异常会发生什么
- 智能指针——如果构造函数抛出怎么办?
- 如果构造函数抛出异常,那么拥有该类的全局对象是否有意义?
- 如果构造函数是私有的,这是怎么做的?
- std::is_default_constructible<T> 错误(如果构造函数是私有的)