0

I am currently reading about the move constructor. I have written the following code

#include <iostream>
#include <cstring>

class foo
{
  private:
  std::string str_member;
  char* char_member ;

  public:
  foo()
  {
    std::cout << "Regular constructor \n";
  }

  foo(const foo& r)
  {
    std::cout << "Copy Constructor \n";

    //Make copies of the contents
    char_member = new char[strlen(r.char_member)+1];
    strcpy(char_member,r.char_member);

    str_member = r.str_member;
  }

  foo& operator=(const foo& r)
  {
    //Do somestuff
    std::cout << "Copy Assignment operator \n";
  }

  //Move Special Member functions

  //Move constructor
  foo(foo&& r)
  {
    //Do somestuff
    std::cout << "move constructor \n";
  }

  //Move Assigment operator
  foo& operator=(foo&& r)
  {
    //Do some stuff
    std::cout << "Move assignment operator";
  }
};


//Some Method that returns an object by value
foo Mymethod()
{   
    foo d;
    return d;
}

int main()
{
    foo p(Mymethod());
    std::cin.get();
}

Output is "Regular constructor".

Now the above class is simply a test class and does not really have the correct copy / assignment / move constructor or move assignment. I am currently only interested in understanding when the move constructor is called. According to my understanding when the function returns a move constructor should be called and then since an rvalue is returned another move constructor should be called.

I have read When Does Move Constructor get called? and aschepler states that:

A move constructor is called:

  • [..]
  • when throwing a function-local class object and the compiler doesn't eliminate the copy/move entirely

Why am I only getting a regular constructor.? I would appreciate it if someone could explain to me why my understanding is wrong. I believe that a move constructor should be called when object is returned from the method and then the move constructor of the foo p should be called.

Community
  • 1
  • 1
MistyD
  • 16,373
  • 40
  • 138
  • 240
  • So you're aware of `-fno-elide-constructors`, then? –  Nov 19 '14 at 05:18
  • It's called *optimisation*. Why would you want the compiler to create an object and move it twice, when it can work out where the object eventually needs to be and create there in the first place? The C++ Standard allows such optimisations. What more do you want to know? Keep in mind that your `MyMethod()` function's implementation is visible in the same translation unit and can easily be "inlined". – Tony Delroy Nov 19 '14 at 05:21
  • Yes. I am however I dont understand how the presence of `-fno-elide-constructors` can cause the code to avoid calling the copy constuctor even once – MistyD Nov 19 '14 at 05:21
  • The answer to that question is found in [C++11: Move/Copy construction ambiguity?](https://stackoverflow.com/questions/9152798/c11-move-copy-construction-ambiguity). [Seth Carnegie](http://stackoverflow.com/a/9152814/3920237): "If [RVO] can't be performed, then it will be a move, because the object being returned is going out of scope (and will be destroyed just after). If it can't be moved, then it will be copied. If it can't be copied, it won't compile." –  Nov 19 '14 at 05:23
  • this is called copy elision [here](http://en.cppreference.com/w/cpp/language/copy_elision) – Rupesh Yadav. Nov 19 '14 at 05:35

0 Answers0