In C++, initialization and assignment are distinct operations.
Through the code snippet below, we will explore these differences.
While examining the code, one might initially assume that IntWrapper’s constructor and destructor are called an equal number of times.
However, this is not the case. IntWrapper is initialized once (through constructor invocation) but assigned multiple times to other variables through copying. For each IntWrapper object, whether created through initialization or assignment, there is a corresponding call to the destructor (typically).
#include <iostream>
class IntWrapper
{
private:
int num;
public:
IntWrapper(int n) : num(n)
{
std::cout << "IntWrapper constructor: " << this << std::endl;
}
~IntWrapper()
{
std::cout << "IntWrapper destructor: " << this << std::endl;
}
};
class App
{
private:
IntWrapper w;
public:
App(IntWrapper v) : w(v)
{
std::cout << "App constructor: " << this << std::endl;
std::cout << "Temp IntWrapper object (v): " << &v << std::endl;
std::cout << "IntWrapper object (v): " << &w << std::endl;
}
~App()
{
std::cout << "App destructor: " << this << std::endl;
std::cout << "IntWrapper object (w): " << &w << std::endl;
}
};
int main()
{
// auto i = IntWrapper(2);
std::cout << "------------ 1 ------------" << std::endl;
IntWrapper i(2);
std::cout << "\n------------ 2 ------------" << std::endl;
App app(i);
std::cout << "\n------------ 3 ------------" << std::endl;
return 0;
}
Output Explanation:
-
A variable
iof typeIntWrapperis created through construction, invoking its constructor. -
An instance of
Appis created by calling its constructor. The previously created variableiis passed by value. Consequently, during the construction of theappinstance, a temporary variablevof typeIntWrapperis created by assignment. Additionally,wis initialized by assignment usingv. Since bothvandware created through assignment, no calls are made to the constructor ofIntWrapper. The temporary variablevis destroyed when it goes out of scope at the end of theAppconstructor. Note: The address ofAppand its propertywis the same because IntWrapper is a simple wrapper, and the underlying data is an int, which C++ optimizes by default. -
At the end of the
mainfunction, all variables go out of scope. The variableapp, created last, is destroyed first, invoking its destructor. Upon destroyingapp, the destructor of its member variablewis also called. Finally, variableiis destroyed.
------------ 1 ------------
IntWrapper constructor: 0x16fd96568
------------ 2 ------------
App constructor: 0x16fd96558
Temp IntWrapper object (v): 0x16fd96554
IntWrapper object (w): 0x16fd96558
IntWrapper destructor: 0x16fd96554
------------ 3 ------------
App destructor: 0x16fd96558
IntWrapper object (w): 0x16fd96558
IntWrapper destructor: 0x16fd96558
IntWrapper destructor: 0x16fd96568