抽象类和移动语义

Nie*_*eru 15 c++ move-semantics c++11

根据"Five of Rule",当我声明其中一个:复制或移动操作或析构函数时,我必须编写所有这些,因为编译器不会为我生成它们(其中一些).但是如果我的class(A)派生自带有虚拟析构函数的抽象类,这是否意味着类中的析构函数A将被视为"用户定义"?因此,移动语义不适用于此类的对象,A因为编译器不会为我生成移动构造函数?

struct Interface {
    virtual void myFunction() = 0;
    virtual ~Interface() {};
};

struct A : public Interface {
    void myFunction() override {};
};
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 11

在[class.copy]中:

如果类的定义X没有显式地声明一个移动构造函数,那么当且仅当
(9.1) - X没有用户声明的复制构造函数时,将隐式声明一个默认值
(9.2) - X没有用户-declared copy assignment operator,
(9.3) - X没有用户声明的移动赋值运算符,
(9.4) - X没有用户声明的析构函数.
[注意:当未隐式声明或显式提供移动构造函数时,否则将调用移动构造函数的表达式可能会调用复制构造函数. - 尾注]

Interface确实有一个用户声明的析构函数,所以Interface移动构造函数不会被隐式声明为默认值.但A不适合任何这些要点的-所以这有一个被默认的隐式转移构造函数.A(A&& )Interface按照说明复制该部分.我们可以通过添加成员来验证这一点InterfaceA:

#include <iostream>

template <char c>
struct Obj {
    Obj() { std::cout << "default ctor" << c << "\n"; }  
    Obj(const Obj&) { std::cout << "copy ctor" << c << "\n"; }
    Obj(Obj&&) { std::cout << "move ctor" << c << "\n"; }
};

struct Interface {
    virtual void myFunction() = 0;
    virtual ~Interface() {};

    Obj<'I'> base;
};

struct A : public Interface {
    void myFunction() override {};

    Obj<'A'> derived;
};

int main() {
    A a1;                      // default I, default A
    std::cout << "---\n";
    A a2(std::move(a1));       // copy I, move A
    std::cout << "---\n";
    A a3(a2);                  // copy I, copy A
}
Run Code Online (Sandbox Code Playgroud)

  • 我不知道.[N3839](http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3839.pdf)探讨了这一点,不确定发生了什么. - 编辑:[EWG#55发生](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4327.html#55)我希望我们得到更多关于它的警告,很快(例如clang ++`-Wdeprecated`). (3认同)
  • 从 C++11 开始,`Interface` 获得默认的复制构造函数是一个不推荐使用的特性。不过,它仍然存在于最近的草稿中。 (2认同)