为什么使用单一的赋值运算符同时处理复制和移动赋值效率不高? [英] Why is it not efficient to use a single assignment operator handling both copy and move assignment?

查看:115
本文介绍了为什么使用单一的赋值运算符同时处理复制和移动赋值效率不高?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是 C ++ Primer 5th Edition 的练习:

练习13.53: 由于效率低下, HasPtr 赋值运算符并不理想.解释为什么.实施 HasPtr 的复制分配和移动分配运算符并进行比较 在新的移动分配运算符中执行的操作与 复制和交换版本.(第544页)

Exercise 13.53: As a matter of low-level efficiency, the HasPtr assignment operator is not ideal. Explain why. Implement a copy-assignment and move-assignment operator for HasPtr and compare the operations executed in your new move-assignment operator versus the copy-and-swap version.(P.544)

文件hasptr.h:

//! a class holding a std::string*
class HasPtr
{
    friend void swap(HasPtr&, HasPtr&);
    friend bool operator <(const HasPtr& lhs, const HasPtr& rhs);
public:
    //! default constructor.
    HasPtr(const std::string &s = std::string()):
        ps(new std::string(s)), i(0)
    { }

    //! copy constructor.
    HasPtr(const HasPtr& hp) :
        ps(new std::string(*hp.ps)), i(hp.i)
    { }

    //! move constructor.
    HasPtr(HasPtr&& hp) noexcept :
        ps(hp.ps), i(hp.i)
    { hp.ps = nullptr; }

    //! assignment operator
    HasPtr&
    operator = (HasPtr rhs);

    //! destructor.
    ~HasPtr()
    {
        delete ps;
    }

private:
    std::string *ps;
    int    i;
};

文件hasptr.cpp的一部分:

//! specific swap.
inline void
swap(HasPtr &lhs, HasPtr &rhs)
{
    using std::swap;
    swap(lhs.ps, rhs.ps); // swap the pointers, not the string data
    swap(lhs.i, rhs.i);   // swap the int members

    std::cout <<"swapping!\n";
}

//! operator = using specific swap
HasPtr&
HasPtr::operator = (HasPtr rhs)
{
    swap(*this,rhs);
    return *this;
} 

我的问题是为什么这样做效率不高?

My question is why it is not efficient to do so?

推荐答案

步骤1

设置性能测试,以练习移动分配运算符.

Set up a performance test which exercises the move assignment operator.

设置另一个性能测试,以测试副本分配操作员.

Set up another performance test which exercises the copy assignment operator.

第2步

按照问题说明中的两种方法设置赋值运算符.

Set up the assignment operator both ways as instructed in the problem statement.

第3步

重复步骤1和2,直到您确信自己正确地完成了操作.

Iterate on Steps 1 and 2 until you have confidence that you did them correctly.

第3步应该可以告诉您发生了什么,很可能是告诉您性能在哪里发生变化在哪里没有发生变化.

Step 3 should help educate you as to what is going on, most likely by telling you where the performance is changing and where it is not changing.

步骤1-3的选项不是猜测.实际上,您必须这样做.否则,您(正确)不会对自己的猜测是正确的.

Guessing is not an option for Steps 1-3. You actually have to do them. Otherwise you will (rightly) have no confidence that your guesses are correct.

第4步

现在,您可以开始猜测.有些人将其称为形成假设".幻想猜"的方式.但是至少现在是受过教育的猜测.

Now you can start guessing. Some people will call this "forming a hypothesis." Fancy way of saying "guessing." But at least now it is educated guessing.

我在回答这个问题的过程中进行了练习,发现其中一项测试没有明显的性能差异,而另一项则有6倍的性能差异.这进一步导致了我的假设.完成这项工作后,如果不确定自己的假设,请使用代码,结果和后续问题来更新您的问题.

I ran through this exercise while answering this question and noted no significant performance difference on one test, and a 6X performance difference on the other. This further led me to an hypothesis. After you do this work, if you are unsure of your hypothesis, update your question with your code, results, and subsequent questions.

说明

有两个特殊的成员分配运算符,通常具有签名:

There are two special member assignment operators which typically have the signatures:

HasPtr& operator=(const HasPtr& rhs);  // copy assignment operator
HasPtr& operator=(HasPtr&& rhs);       // move assignment operator

可以使用一个单独的赋值运算符同时实现移动赋值和复制赋值,即所谓的复制/交换"习惯用法:

It is possible to implement both move assignment and copy assignment with a single assignment operator with what is called the copy/swap idiom:

HasPtr& operator=(HasPtr rhs);

第一个集合不能重载此单个赋值运算符.

This single assignment operator can not be overloaded with the first set.

使用复制/交换习语实现两个赋值运算符(复制和移动)还是仅实现一个赋值运算符更好?这就是练习13.53所要问的.要进行回答,您必须同时尝试两种方法,并同时测量复印分配和移动分配.聪明,善意的人们会通过猜测而不是测试/测量来弄错这一点.您已经选择了一种好运动来学习.

Is it better to implement two assignment operators (copy and move), or just one, using the copy/swap idiom? This is what Exercise 13.53 is asking. To answer, you must try both ways, and measure both copy assignment and move assignment. And smart, well meaning people get this wrong by guessing, instead of testing/measuring. You have picked a good exercise to study.

这篇关于为什么使用单一的赋值运算符同时处理复制和移动赋值效率不高?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆