C++

C++ - [OOP] Initialization

Default Initialization, Memory Order

Posted by Rico's Nerd Cluster on March 1, 2023

Default Initialization

Default Initialization is when a variable is initialized without explicit value. They could be in an uninitialized state and accessing them could be an undefined behavior.

  • POD types like int, float are initialized to an intermediate value. Accessing them without initialization is an undefined behavior,
    • Default initialization guarantees to initialize POD data, but not array data
  • User defined types should either have no constructor provided, or have a default constructor present.
1
2
3
4
5
6
7
8
class A{
    A(){};  // This is NOT default initialization
    A() = default;  // This IS default initialization
};

class B{
    int value;  // There's a synthesized default initializer as well.
};
  • static storage duration always default initializes to 0, whereas automatic storage variables are default initialized to intermediate values
1
2
3
4
5
6
7
int x;          // automatic storage, intermediate value
static int y;   // default initialized to 0
int *j;         // automatic storage, intermediate value
static int *p   // static storage, default initialized to nullptr

int arr[5];        // Elements have indeterminate values
static int arr[5]; // All elements default-initialized to 0

Best Practices:

  • Use brace initialization {} (C++ 11) to explicitly initialize variables
1
int i{};    // explicitly initialized to 0;

Initialization Order

We need to make sure the vairable order is consisntent in both the initializer list and the variable definition. One common warning we see is warning: <VAR> will be initialized after [-Wreorder]

1
2
3
4
5
6
7
8
9
10
11
12
class MyClass{
    /*
        * Below public functions are defined in the order of operation
    */
    public:
        // Step 0: Create this object when first powered on
        MyClass(): previous_time_(millis()), current_status_(Status::UNINITIALIZED)
        {}

        Status current_status_;
        unsigned long previous_time_;
};
  • The order of class variable initialization is determined by the declaration order, not the order in initializers. Reference

Memory Order of Class Members

Declaration Order: Variables appear in memory in the order they are declared in the struct/class.

1
2
3
4
5
struct Example {
    int a;     // Offset 0
    double b;  // Offset 8 (if 8-byte alignment is required for double)
    char c;    // Offset 16 (next available slot for alignment)
};

Default Parameters

  • Default values are given in .hpp files, not .cpp. In .hpp file, do void VoxelGrid(CloudPtr cloud, float voxel_size = 0.05);. You wouldn’t need it in the .cpp files

Ctor for Inheritance

  • Python would allow a child class without a ctor if parent has a ctor with args. C++ wouldn’t. we need to define a ctor for the child class too
    1
    2
    3
    4
    5
    6
    7
    8
    
      class Parent:
          def __init__(self, x):
              self.x = x
    
      class Child(Parent):
          pass  # No constructor
    
      c = Child(42)  # ✅ Works fine in Python
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      class Parent {
      public:
          Parent(int x) {}  // no default constructor
      };
    
      class Child : public Parent {
          // No constructor → ❌ compile error
      };
    
      Child c(42);  // 💥 Error: no matching constructor for 'Child'