0


As I was going through the C++ book by Siddhartha Rao, I came across the following code (pardon the lack of proper spacing):

 #include <iostream>
 #include <algorithm>
 using namespace std;

 class MyBuffer
 {
public:
 int* myNums;
 unsigned int bufLength;
 
 MyBuffer(unsigned int length)
 {
 bufLength = length;
 cout << "Constructor allocates " << length << " integers" << endl;
 myNums = new int[length]; // allocate memory
 }

 MyBuffer(const MyBuffer& src) // copy constructor
 {
 cout << "Copy constructor creating deep copy" << endl;
 bufLength = src.bufLength;
 myNums = new int[bufLength];
 copy(src.myNums, src.myNums + bufLength, myNums); // deep copy
 }

// move constructor
MyBuffer(MyBuffer&& moveSource)
{
cout << "Move constructor working here!" << endl;   
if(moveSource.myNums != NULL)
{
myNums = moveSource. myNums; // take ownership i.e. ’move’
moveSource.myNums = NULL; // set the move source to NULL
}
}

 ~MyBuffer()
 {
 cout << "Destructor releasing allocated memory" << endl;
 delete[] myNums; // free allocated memory
 }

 void SetValue(unsigned int index, int value)
 {
 if (index < bufLength) // check for bounds
 *(myNums + index) = value;
 }

 void DisplayBuf()
 {
 for (unsigned int counter = 0; counter < bufLength; ++counter)
 cout << *(myNums + counter) << " ";

 cout << endl;
 }
 };

MyBuffer Copy(MyBuffer& source) // function
{
MyBuffer copyForReturn(source.bufLength); // create copy
return copyForReturn; // return by value invokes copy constructor
} 

int main()
{
MyBuffer buf1(5);
MyBuffer buf2 = Copy(buf1); // invokes 1x copy, 1x move constructor
return 0;
}

I can understand that move constructor is implemented to avoid deep copying when returning by value. However, as a check I added this line in the move constructor code: cout << "Move constructor working here!" << endl;
But the thing is that it is not getting printed in the output.
My output is
Constructor allocates 5 integers Constructor allocates 5 integers Destructor releasing allocated memory Destructor releasing allocated memory
Does it mean that move constructor is not getting invoked?

paapi_420
  • 1
  • 2
  • Indeed, you are getting Named Return Value Optimisation (NRVO). Compiler is allowed to optimise away copy/move constructor calls. – Yksisarvinen Jul 22 '23 at 11:11
  • Any book that still uses `using namesapce std;` and `new int[bufLength]` is IMO out-of-date, this is what C++ has had `std::vector` for since C++98. You should use `std::vector myNums(bufLength);` – Pepijn Kramer Jul 22 '23 at 11:12
  • Also, return by value is not calling the copy constructor here. Can you please explain that too? – paapi_420 Jul 22 '23 at 11:49
  • *I added this line* -- And I added these lines in `main`: `MyBuffer buf3(10); buf2 = buf3;` and the whole thing fell to pieces. – PaulMcKenzie Jul 22 '23 at 11:51
  • *return by value is not calling the copy constructor here* -- [Copy elision](https://en.cppreference.com/w/cpp/language/copy_elision) – PaulMcKenzie Jul 22 '23 at 11:57
  • Thanks @PaulMcKenzie for pointing out the answer. I am still at the beginning stage and had not encountered the copy elison. – paapi_420 Jul 23 '23 at 08:40

0 Answers0