【问题标题】:Move constructor issue移动构造函数问题
【发布时间】:2013-01-03 19:06:01
【问题描述】:

我有以下课程:

class Student
{
private:
    std::string firstName;
    std::string lastName;
public:
    Student():firstName(""), lastName("") 
    { 
    }

    Student(const std::string &first, const std::string &last)
        :firstName(first), lastName(last) 
    {
    }

    Student(const Student &student)
        :firstName(student.firstName), lastName(student.lastName)
    {
    }

    Student(Student &&student)
    {
        firstName=std::move(student.firstName);
        lastName=std::move(student.lastName);
    }

    // ... getters and setters    
};

我是这样使用的:

std::vector<std::shared_ptr<Student>> students;
std::shared_ptr<Student> stud1 = std::make_shared<Student>("fn1","ln1");
students.push_back(stud1);
Student stud2("fn2","ln2");
students.push_back(std::make_shared<Student>(std::move(stud2)));

根据我的阅读,编译器自动生成了移动构造函数。 现在,当我踏入students.push_back(std::make_shared&lt;Student&gt;(std::move(stud2))); 这一行时,我到达了移动构造函数,这没关系。

如果我在进入该行时注释掉移动构造函数,我会到达复制构造函数。 我不明白为什么会这样。

【问题讨论】:

  • IIRC,编译器自动生成复制构造函数。移动构造函数不会自动生成。
  • 移动构造函数仅在特定条件下自动生成:stackoverflow.com/questions/4943958/…
  • (我很好奇你为什么不在移动构造函数中使用初始化列表。)
  • 对不起,Mat,但不知道你是什么意思,我是 C++ 新手
  • 除了移动构造函数外,您在任何地方都使用Student(...) : firstName(...) {} 语法。那很奇怪。您也可以在那里使用它,并可能节省两个字符串结构。

标签: c++ visual-c++ c++11 visual-studio-2012 move-semantics


【解决方案1】:

Visual C++ 2012 不会隐式生成移动构造函数或移动赋值运算符。

(控制何时隐式声明和定义移动操作的规则在标准化过程中多次更改;Visual C++ 2012 不支持 标准化(2011 年)规则集。)

【讨论】:

    【解决方案2】:

    在您的情况下,您可以简单地声明所有这些构造函数=default,例如

    class student
    {
      std::string firstname, surname;
    public:
      student(student const&) = default;
      student(student&&) = default;
      student&operator=(student const&) = default;
      student&operator=(student&&) = default;
      // etc
    };
    

    不要担心细节:编译器应该解决这个问题并生成对std::string::string(string&amp;&amp;)的适当调用(移动构造函数)。

    编辑当然,这不适用于有缺陷的编译器,但如果您标记“C++11”,那么您应该期待 C++11 的答案。

    【讨论】:

    • 我读到了这个特性,但不幸的是 Visual Studio 2012 仍然不支持所有 c++11 特性(默认方法是其中之一)
    • @JackWillson 最后连移动成员的自动生成都不支持。
    • @JackWillson :您使用的编译器完全改变了这里的答案(因为它有缺陷)。下次请在您的原始问题中包含编译器和版本。
    • 我会的,抱歉省略了。
    猜你喜欢
    • 1970-01-01
    • 2019-05-17
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 2017-11-03
    • 2014-11-08
    相关资源
    最近更新 更多