My Question: Why is the class working properly? Without showing any errors? I was expecting it to crash or malfunction such as outputting garbage values.
'
class Pizza
{
public:
Pizza(std::string string) { std::cout << "Ctor :" << string << std::endl; }
~Pizza() { std::cout << "Dtor" << std::endl; }
Pizza(const Pizza& rhs){ std::cout << "Copy Constructor" << std::endl; }
Pizza& operator=(const Pizza& rhs){ std::cout << "Assignment Operator" << std::endl;}
void display(){std::cout << "Display method is called on Pizza" << std::endl; }
};
int main()
{
Pizza pizza = Pizza("1");
Pizza tizza = pizza;
tizza = pizza;
pizza.display();
tizza.display();
}'
The output for the code with g++ (Mingw Compiler) on windows 10 and other compilers too is:
Ctor :1
Copy Constructor
Assignment Operator
Display method is called on Pizza
Display method is called on Pizza
Dtor
Dtor
Looks like I found the reason:
Thanks to @Igor Tandetnik, he had mentioned the same thing in comment on the same day when the question was asked. However since, the comment was brief and I'm still in learning phase, I was unable to get the whole picture from the comment. Hence, decided to write the answer, with a bit of explanation. Which will be helpful for someone like me, Some day :) .
Reason:
- I haven't being using the any data members in the class.
- I'm only using the class method in the above code. Since, all the objects uses the same class methods (i.e., class methods are per class, not per object.)
- The main motive of the copy constructor is to copy the data members from one object of the class to another object.
- I haven't declared any non-static data member for the class, which are created per object. Declaring non-static members for the above would surely result in undefined behavior of the class. Such data members having garbage values.
- Hence, the above code works fine with non-correct copy constructor and move assignment operator.
Below is the code which will give the garbage values for the data members because of incorrect assignment operator and copy constructor.
//g++ 5.4.0
#include <iostream>
class Pizza
{
public:
Pizza(std::string string, int data) : m_string(string), m_data(data) { std::cout << "Ctor :" << string << std::endl; }
~Pizza() { std::cout << "Dtor" << std::endl; }
void set(std::string string, int data) { m_string = string; m_data = data; }
Pizza(const Pizza& rhs){ std::cout << "Copy Constructor" << std::endl; }
Pizza& operator=(const Pizza& rhs){ std::cout << "Assignment Operator" << std::endl;}
void display()
{
std::cout << "Display method is called on Pizza" << std::endl;
std::cout << "string: " << m_string << " Data: " << m_data << std::endl;
}
private:
std::string m_string;
int m_data;
};
int main()
{
Pizza pizza = Pizza("Test", 99);
Pizza tizza = pizza;
tizza = pizza;
pizza.display();
tizza.display();
}
Bottom Line: Copy constructor, move constructor, assignment operator will make sense the most only when the class has non-static data members.