简体   繁体   English

复制和交换习语和移动操作之间的交互

[英]Interaction between copy-and-swap idiom and move operations

I'm trying to make a program that implements the interaction between "copy and swap" idiom and and move control operations so I wrote this code:我正在尝试制作一个程序来实现“复制和交换”习语和move control operations之间的交互,因此我编写了以下代码:

class PInt
{
public:
    PInt(int = 0);
    PInt(const PInt&);
    PInt(PInt&&) noexcept;
    PInt& operator=(PInt);
    ~PInt();

    int* getPtr()const;

private:
    int* ptr;
    friend void swap(PInt&, PInt&);
};

PInt::PInt(int x) : 
    ptr(new int(x))
{
    std::cout << "ctor\n";
}

PInt::PInt(const PInt& rhs) :
    ptr(new int(rhs.ptr ? *rhs.ptr : 0))
{
    std::cout << "copy-ctor\n";
}

PInt::PInt(PInt&& rhs) noexcept :
    ptr(rhs.ptr)
{
    std::cout << "move-ctor\n";
    rhs.ptr = nullptr; // putting rhs in a valid state
}


PInt& PInt::operator=(PInt rhs)
{
    std::cout << "copy-assignment operator\n";
    swap(*this, rhs);
    return *this;
}

PInt::~PInt()
{
    std::cout << "dtor\n";
    delete ptr;
}

void swap(PInt& lhs, PInt& rhs)
{
    std::cout << "swap(PInt&, PInt&\n";
    using std::swap;
    swap(lhs.ptr, rhs.ptr);
}

PInt gen_PInt(int x)
{
    return {x};
}

int main()
{
    PInt pi1(1), pi2(2);
    //pi1 = pi2; // 1
    //pi1 = PInt{}; // 2
    //pi1 = std::move(pi2); // 3
    pi1 = std::move(PInt{}); // 4


}
  • Everything is OK for me so I think in 1 the copy-ctor is invoked by copy-asignment operator to initialize its parameter (it takes by value) then uses swap.对我来说一切都很好,所以我认为在1 ,copy-ctor 由 copy-asignment 运算符调用以初始化其参数(按值获取),然后使用交换。 in "2" I am assigning from an r-value thus I think the compiler applies some "Copy-elision" optimization;在“2”中,我从 r 值分配,因此我认为编译器应用了一些“复制省略”优化; creating directly an object in the copy-assignment operator.在复制赋值运算符中直接创建一个对象。

  • What I am not sure of is from 3 and 4. so here is the result of 3 and 4:我不确定的是 3 和 4。所以这是 3 和 4 的结果:

    un-commenting line 3:取消注释第 3 行:

     ctor ctor move - ctor copy - assignment operator swap(PInt&, PInt & dtor dtor dtor

Un-commenting line 4:取消注释第 4 行:

    ctor
    ctor
    ctor
    move - ctor
    copy - assignment operator
    swap(PInt&, PInt &
    dtor
    dtor
    dtor
    dtor
  • Why 3 and 4 use std::move but for gets n extra constructor called?为什么 3 和 4 使用std::move但调用了 n 个额外的构造函数?

** Which is efficient: defining a copy/move-assignment operator taking by value or two separate versions : copy assignment and move assignment? ** 哪个是有效的:定义一个按值获取的复制/移动赋值运算符或两个单独的版本:复制赋值和移动赋值? Because the one version each time called it either calls (extra call) copy-ctor or move-ctor to initialize its parameter?因为一个版本每次调用它要么调用(额外调用)copy-ctor 或 move-ctor 来初始化它的参数?

Why 3 and 4 use std::move but for gets n extra constructor called?为什么 3 和 4 使用 std::move 但调用了 n 个额外的构造函数?

The "extra" (move) constructor for 3 and 4 is to create the object that is the argument here: 3 和 4 的“额外”(移动)构造函数用于创建作为此处参数的对象:

PInt& PInt::operator=(PInt rhs)
                      ^^^^^^^^

The "extra" constructor for 4 is to create this temporary: 4 的“额外”构造函数是创建这个临时的:

pi1 = std::move(PInt{}); // 4
                ^^^^^^

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM