I am trying to learn when and why constructors, assignments, and destructors are called in c++. I created a few sample codes to practice and I will tell you which parts I don't understand and I will also tell you what is printed when compiling and running the codes. I am compiling and running in ubuntu's terminal and using the flags -std=c++11 and -fno-elide-constructors so that the terminal prints every constructor.
DEFAULT CONSTRUCTOR for first
DEFAULT CONSTRUCTOR for second
COPY ASSIGNMENT for first
DEFAULT CONSTRUCTOR for third
FUNCTION CALLING
DEFAULT CONSTRUCTOR for temporary
MOVE CONSTRUCTOR for
DESTRUCTOR for temporary
MOVE ASSIGNMENT for third
DESTRUCTOR for
FUNCTION FINISHED
7
DESTRUCTOR for third
DESTRUCTOR for second
DESTRUCTOR for first
I understand why everything is called before "FUNCTION CALLING" and after "FUNCTION FINISHED" but I am not sure about the part inside the function. Is "MOVE CONSTRUCTOR for" creating a temporary rvalue? Then "MOVE ASSIGNMENT for third" comes from the line in main "object3=myFunction();" I think. Then "DESTRUCTOR for" is destroying the rvalue. Is this correct? Why is c++ creating a temporary object in the function when the function doesn't do anything?
DEFAULT CONSTRUCTOR for first
DEFAULT CONSTRUCTOR for second
COPY ASSIGNMENT for first
DEFAULT CONSTRUCTOR for third
FUNCTION CALLING
COPY CONSTRUCTOR for
MOVE CONSTRUCTOR for
MOVE ASSIGNMENT for third
DESTRUCTOR for
DESTRUCTOR for
FUNCTION FINISHED
7
DESTRUCTOR for third
DESTRUCTOR for second
DESTRUCTOR for first
Again, here I understand everything that is called outside the function, what I don't understand is why "COPY CONSTRUCTOR for", "MOVE CONSTRUCTOR for", and the two "DESTRUCTOR for" are called? Can someone explain to me what the compiler is doing inside the function?
Your move assignment is not actually implemented. Try something on the lines of:
1 2 3 4 5 6 7
#include <utility> //std::move()
//
MyClass::MyClass(MyClass && moveFrom){
name = std::move(moveFrom.name);
std::cout<<"MOVE CONSTRUCTOR for " <<name <<std::endl;
//I used a struct with public access specifiers instead of class
}
You'll find the results are quite different in this case, viz:
1 2 3 4 5 6 7 8 9 10 11 12 13
DEFAULT CONSTRUCTOR for first
DEFAULT CONSTRUCTOR for second
COPY ASSIGNMENT for first
DEFAULT CONSTRUCTOR for third
FUNCTION CALLING
DEFAULT CONSTRUCTOR for temporary
MOVE ASSIGNMENT for third
DESTRUCTOR for temporary
FUNCTION FINISHED
7
DESTRUCTOR for third
DESTRUCTOR for second
DESTRUCTOR for first