c++11 move not take effective?

99封情书 提交于 2019-12-24 10:37:09

问题


I tested c++11 move function, but not become effective. Who can tell me why ? Thanks. The code is as follows:

class Base {
  public:
   Base() { cout << "Base" << endl;}
   ~Base() { cout << "~Base" << endl;}

   Base(const Base& base) { cout << "Copy" << endl; }
   Base& operator=(const Base& base) {cout << "operator=" << endl;}

   Base(Base&& base) { cout << "move" << endl;}
   Base& operator=(Base&& base) { cout << "move=" << endl;}
};

Base b;

Base&& GetResult() {
  return std::move(b);
} 

int main() {
Base&& tmp = GetResult();

cout << &b << endl;
cout << &tmp << endl;

}

Output:

 Base
 0x6013a0
 0x6013a0
 ~Base

Why move copy and move operator= not be called ? And why address is the same ?


回答1:


To add to the excellent existing answers, I believe the main point of confusion here is what std::move does.

std::move does not move.

It was abysmally named.

It only gives you an xvalue referring to whatever you gave it; this xvalue will bind to a rvalue reference where an lvalue won't. This means the result of std::move can be given to a move constructor or move assignment operator. However, it does not do that for you, and you do not do it here.


Given such strong criticism for the naming, surely you have an alternative suggestion
– user2079303

This is a well-trodden topic, but the creator of C++ suggests std::rval, and one of the architects of modern C++ suggests std::rvalue_cast (even though you actually get an xvalue).

Personally, I think std::moveable would have been a nice middle ground.




回答2:


Why move copy and move operator= not be called ?

I assume that by "move copy" you mean "move constructor". Move assignment operator is not called, because you never use the assignment operator.

There are no moves (nor copies) because Base&& is a reference (an r-value reference to be specific). References refer / point to an object - they do not contain state of the object. When you initialize a reference, no object is copied or moved.

And why address is the same ?

When the address-of operator is applied to a reference, you get the address of the referred object.




回答3:


Let's ignore move semantics for a minute, and only think about familiar, C++98 copy constructors. Given the following code, what output would you expect?

class Base {
  public:
   Base() { cout << "Base" << endl;}
   ~Base() { cout << "~Base" << endl;}

   Base(const Base& base) { cout << "Copy" << endl; }
   Base& operator=(const Base& base) {cout << "operator=" << endl;}
};

Base b;

Base& GetResult() {
  return b;
} 

int main() {
  Base& tmp = GetResult();

  cout << &b << endl;
  cout << &tmp << endl;
}

Of course, you would expect a call to the Base default constructor, followed by the address of b printed twice, followed by the Base destructor. The reason is because you're only constructing one Base instance, and never copying it -- you're only using references.

So it is with your example. You're using rvalue references rather than lvalue references, but the point is the same -- there is only ever one Base variable, and no copying or moving ever happens. If you want to witness move semantics in action, you could try something like this:

Base getBase() {
    return Base{};
}

int main() {
    Base tmp = getBase();
    Base other = std::move(tmp);
}

(The move out of getBase() will probably be optimised out by the compiler, but you should still see the second one.)



来源:https://stackoverflow.com/questions/43523753/c11-move-not-take-effective

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