Why is it not efficient to use a single assignment operator handling both copy and move assignment?

血红的双手。 提交于 2019-12-02 21:19:52

Step 1

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

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

Step 2

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

Step 3

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

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.

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.

Step 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.

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.

Clarification

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.

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.

As the problem suggests, it's "a matter of low-level efficiency". When you use HasPtr& operator=(HasPtr rhs) and you write something like hp = std::move(hp2);, ps member is copied twice (the pointer itself not the object to which it points): Once from hp2 to rhs as a result of calling move constructor, and once from rhs to *this as a result of calling swap. But when you use HasPtr& operator=(HasPtr&& rhs), ps is copied just once from rhs to *this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!