gpt4 book ai didi

c++ - 如果有成员,则基类中的默认析构函数禁用子类中的move构造函数

转载 作者:行者123 更新时间:2023-12-01 14:43:29 25 4
gpt4 key购买 nike

为什么Base1中的默认(用户声明的)析构函数阻止了Child1类中的移动构造函数/运算符的生成,但是当我将成员data从Base(Base2)移到Child(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( default)中将析构函数声明为“ BaseDel”时,那么move构造函数在Base( deleted)和Child( BaseDel)类中应为“ ChildDel”。它是否正确?我认为,成员(member)位置无关紧要。如果我明确地执行此操作,则会收到预期的错误:

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
}

最佳答案

隐式move构造函数不会(仅)删除,当您拥有用户声明的析构函数时,它不会首先声明,就像Base1Base2一样。

因此,在重载解析中永远不要考虑move构造函数,因此auto obj1 = std::move(c1);虽然可以调用Child1的move构造函数,但需要回退以复制Base1子对象的构造。
Base1Child1的隐式声明的副本构造函数都定义为已删除,因为Data的隐式声明的副本构造函数被定义为Deleted,因为Data具有用户定义的move构造函数。因此,auto obj1 = std::move(c1);将失败,并出现一个错误,即删除了隐式声明的副本构造函数。

对于Base2,副本构造函数未定义为已删除,因为它没有Data成员,因此auto obj2 = std::move(c2);将调用Child2的move构造函数(也使用Data的move构造函数),但对Base2子对象使用copy构造函数。

关于c++ - 如果有成员,则基类中的默认析构函数禁用子类中的move构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60126847/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com