首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++引物5编辑。虚拟析构函数和移动语义

C++引物5编辑。虚拟析构函数和移动语义
EN

Stack Overflow用户
提问于 2020-07-18 22:36:04
回答 1查看 92关注 0票数 0

在C++引物第5版。据说:

“基类需要虚拟析构函数这一事实对基类和派生类的定义有着重要的间接影响:如果一个类定义了析构函数--即使它使用=默认值使用合成版本--编译器也不会为该类合成移动运算符(§13.6.2,第537页)。”

为了获得更多的理解,我尝试了这样的方法:

代码语言:javascript
复制
class A
{
public:
    A(){cout << "A::A()\n";}
    virtual ~A(){cout << "A::~A()\n";}
    A& operator = (const A&) {cout << "A::=\n"; return *this;};
    A& operator = (A&&) = default;
};

int main()
{

    A a;
    A a2;
    a2 = std::move(a); // why copy-assignment operator is not called here. Normally a will be "moved" through copy-ctor (moving through working copy-ctor)


    std::cout << std::endl;
}
  • 因此,根据上面书中的文本,class A有一个virtual析构函数,因此编译器不会合成移动ctor/赋值操作,但是在main中,我尝试移动一个class A类型的对象,所以通常move这里使用复制赋值而不是移动赋值,但是这里不调用复制分配?!
  • 那么,当一个坏的dtor导致默认操作不被合成时呢?谢谢!
EN

回答 1

Stack Overflow用户

发布于 2020-07-18 23:02:03

你的教科书是对的,编译器不会自动合成一个移动操作符。在代码示例中,您通过将编译器设置为默认来强制编译器生成一个,只有在隐式删除move运算符时才会失败。而不是含蓄地声明。

隐式删除准则

  • A有一个非静态数据成员,即const。
  • A具有引用类型的非静态数据成员。
  • A具有不可移动分配的非静态数据成员(已删除、不可访问或不明确的移动赋值运算符)。
  • 具有不能移动分配的直接或虚拟基类(已删除、不可访问或不明确的移动赋值运算符)
  • A具有非静态数据成员或直接或虚拟基,而没有移动赋值运算符,这些运算符都是不可复制的。
  • A具有直接或间接的虚拟基类。

隐式声明准则

  • 没有用户声明的副本构造函数;
  • 没有用户声明的移动构造函数;
  • 没有用户声明的副本分配操作符;
  • 没有用户声明的析构函数;
  • 隐式声明的移动赋值运算符不会被定义为已删除。

来源

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62974462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档