实现构造函数是否会阻止自动移动语义?

时间:2016-10-21 14:36:46

标签: c++ c++11

我一直在阅读C ++ 11的新移动语义,而且我不清楚的是,如果使用自定义构造函数会阻止编译器自动向您的类添加移动语义。我不明白5的规则是否也包括如下的简单类。

我有以下课程:

class CodeFile
{
private:
    std::vector<Function> functions;
    //std::vector<std::wstring, unsigned long> variables;
    std::vector<std::wstring> lines;
    std::vector<unsigned char> constants;

public:
    std::wstring directory;
    std::wstring fileName;

    void setFilePath(std::wstring filePath);
    bool addFunction(Function function);
    void Run();
    void Finalize();

    CodeFile(std::wstring filePath);
};

最后一行是构造函数。定义此构造函数是否会阻止编译器通过添加移动构造函数来优化类?

我应该将该课程声明如下吗?

class CodeFile
{
private:
    std::vector<Function> functions;
    //std::vector<std::wstring, unsigned long> variables;
    std::vector<std::wstring> lines;
    std::vector<unsigned char> constants;

public:
    std::wstring directory;
    std::wstring fileName;

    void setFilePath(std::wstring filePath);
    bool addFunction(Function function);
    void Run();
    void Finalize();
    static CodeFile fromFile(std::wstring filePath);
};

2 个答案:

答案 0 :(得分:3)

您无需在此处执行任何操作。 C ++将为您编写移动构造函数。

但是,无论何时您担心这一点,只需添加

即可
CodeFile(CodeFile &&)=default;
CodeFile(CodeFile const&)=default;
CodeFile& operator=(CodeFile &&)=default;
CodeFile& operator=(CodeFile const&)=default;

可能

CodeFile()=default;

这是一个令人烦恼的样板,但它也是无害的,并表示你希望这个类是可复制的和可移动的(或者你是疯狂的通用代码,并希望它的复制/可移动性依赖于它的父母和内容)。

请注意,除非是真正的转换,否则你不应该有一个非显式的单一参数构造。请考虑explicit上的CodeFile(std::wstring)

但是,任何禁用CodeFile(CodeFile&&)自动书写功能的内容也会禁用CodeFile(CodeFile const&)的自动书写功能。因此,如果您发现无法再复制它,您也可以不再移动它(除非您手动编写CodeFile(CodeFile const&),这当然会在不禁用自身的情况下禁用CodeFile(CodeFile&&)。)。

为了诊断这样的事情,我经常写noisy

struct noisy {
  noisy(){std::cout << "ctor()\n";}
  noisy(noisy&&){std::cout << "ctor(&&)\n";}
  noisy(noisy const&){std::cout << "ctor(c&)\n";}
  void operator=(noisy&&){std::cout << "asgn(&&)\n";}
  void operator=(noisy const&){std::cout << "asgn(c&)\n";}
  ~noisy() {std::cout << "~\n"; }
};

除了发出噪音外什么也没做。

然后我们写一个玩具类型:

struct Foo {
  Foo (int) {}
  noisy _;
};

我们关心的属性。

进行一些测试:

Foo f(7);
f = Foo(3);
Foo f2=std::move(f);

表明移动构造函数很好。我们编写Foo

仅从Foo(int)中删除了默认构造函数

live example

答案 1 :(得分:1)

  

我应该将该课程声明如下吗? ...

没有。只需声明您需要自动生成的构造函数,如下所示

CodeFile(CodeFile&&) = default;