【问题标题】:Creating a new class object and move semantics [closed]创建一个新的类对象并移动语义[关闭]
【发布时间】:2020-09-01 21:08:14
【问题描述】:

拥有这个简单的类:

#include <iostream>

class B 
{ 
public:  
    //default constructor
    B(const char* str = "\0") {
        std::cout << "Constructor called\n";
    }

    //copy constructor
    B(const B& b)   {
        std::cout << "Copy constructor called\n";
    }

    //move constructor
    B(B&& b) {
        std::cout << "Move constructor called\n";
    }
}; 

这些语句在移动语义方面有什么区别:

B o1 = B("abc");
B o2 = B(B("abc")); 

这两行是等价的吗?

【问题讨论】:

  • 这取决于您使用的 C++ 版本
  • 这并没有解决问题,但”\0” 是一个由 两个 nul 字符组成的数组。将”” 用于空字符串。
  • @Derek81 在这两种情况下都会有复制/移动省略。
  • @Derek81 是的,会有复制省略 (RVO),但如果您在 C++11 和 14 中使用 B(B&amp;&amp;) = delete; 禁止它,则不会。在 C++17 中,省略是强制性的,如果您 delete 示例中的复制 ctor/赋值运算符和移动 ctor/赋值运算符都没关系 - 代码将编译并总共创建 2 个对象。跨度>
  • @Derek81:在 C++17 之前,大多数编译器仍然有 RVO,但不能保证。如果你的编译器没有这样做,你可能会看到一个 default->copy,然后是 default->move->copy。

标签: c++ constructor move-semantics copy-elision


【解决方案1】:

从 C++17 开始有一条规则,即从相同类型的纯右值初始化对象意味着没有临时实现:纯右值的参数成为结果对象的参数。无论该类型具有什么构造函数,这都是正确的。

在代码术语中,这意味着 T x = T(args);T x(T(args));T x(args); 的含义完全相同——但没有最令人烦恼的解析的可能性。

所以你的两个例子都等价于B o3("abc");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-14
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多