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).

► Run this code

#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:

  1. A variable i of type IntWrapper is created through construction, invoking its constructor.

  2. An instance of App is created by calling its constructor. The previously created variable i is passed by value. Consequently, during the construction of the app instance, a temporary variable v of type IntWrapper is created by assignment. Additionally, w is initialized by assignment using v. Since both v and w are created through assignment, no calls are made to the constructor of IntWrapper. The temporary variable v is destroyed when it goes out of scope at the end of the App constructor. Note: The address of App and its property w is the same because IntWrapper is a simple wrapper, and the underlying data is an int, which C++ optimizes by default.

  3. At the end of the main function, all variables go out of scope. The variable app, created last, is destroyed first, invoking its destructor. Upon destroying app, the destructor of its member variable w is also called. Finally, variable i 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