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
i
of typeIntWrapper
is created through construction, invoking its constructor. -
An instance of
App
is created by calling its constructor. The previously created variablei
is passed by value. Consequently, during the construction of theapp
instance, a temporary variablev
of typeIntWrapper
is created by assignment. Additionally,w
is initialized by assignment usingv
. Since bothv
andw
are created through assignment, no calls are made to the constructor ofIntWrapper
. The temporary variablev
is destroyed when it goes out of scope at the end of theApp
constructor. Note: The address ofApp
and its propertyw
is 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
main
function, all variables go out of scope. The variableapp
, created last, is destroyed first, invoking its destructor. Upon destroyingapp
, the destructor of its member variablew
is also called. Finally, variablei
is 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