C++ Object Characteristics: Constructors, Destructors, and Member Functions

Object Initialization and Cleanup

Proper object initialization and cleanup are critical for program safety. Uninitialized objects yield undefined behavior, while improper cleanup causes resource leaks. C++ uses constructors and destructors to address these issues:

Constructors

  • Syntax: ClassName() {}
  • No return type (not even void)
  • Name matches class name
  • Supports parameters and overloading
  • Automatically invoked during object creation

Destructors

  • Syntax: ~ClassName() {}
  • No return type or parameters
  • Cannot be overloaded
  • Automatically invoked before object destruction
#include <iostream>
using namespace std;

class Entity {
public:
  Entity() { cout << "Constructor called" << endl; }
  ~Entity() { cout << "Destructor called" << endl; }
};

void testFunction() {
  Entity localEntity; // Stack allocation
}

int main() {
  Entity mainEntity;
  testFunction();
  
  Entity* heapEntity = new Entity; // Heap allocation
  delete heapEntity;
  
  return 0;
}

Constructor Types and Invocation

Constructors are categorized by parameters (parameterized/default) and type (regular/copy). Three invocation methods exist:

class Data {
public:
  int value;
  
  Data() : value(0) { 
    cout << "Default constructor: " << value << endl; 
  }
  
  Data(int v) : value(v) { 
    cout << "Parameterized constructor: " << value << endl; 
  }
  
  Data(const Data& src) : value(src.value) { 
    cout << "Copy constructor: " << value << endl; 
  }
};

void demo() {
  Data d1; // Default
  Data d2(5); // Explicit parameterized
  Data d3(d2); // Copy
  
  Data d4 = Data(10); // Explicit declaration
  Data d5 = 15; // Implicit conversion
}

Copy Constructor Scenarios

Copy constructors are invoked in three cases:

  1. Initializing new objects from existing ones
  2. Passing objects by value to functions
  3. Returning objects by value from functions
class Counter {
public:
  int count;
  
  Counter(int c) : count(c) {}
  Counter(const Counter& src) : count(src.count) {}
};

void increment(Counter c) {} // Copy during parameter passing

Counter createCounter() {
  Counter temp(5);
  return temp; // Potential copy during return
}

Constructor Rules

Compiler-provided special functions:

  1. Default constructor (parameterless)
  2. Default copy constructor (member-wise copy)
  3. Default destructor

Implementation rules:

  1. Defining any constructor suppresses default constructor generation
  2. Defining a copy constructor suppresses other constructor generatino

Static Members

Static Member Variables

  • Shared across all class instances
  • Initialized outside class definition
class SharedData {
public:
  static int sharedValue;
};

int SharedData::sharedValue = 100;

Static Member Functions

  • Can only access static members
  • No this pointer
class MathUtil {
public:
  static double square(double x) { return x * x; }
};

Member Storage Separation

Only non-static data members reside within class objects:

class Empty {};
class WithData { int x; };
class WithStatic { static int y; };

// Sizes:
// Empty: 1 byte (minimum size)
// WithData: sizeof(int)
// WithStatic: sizeof(int) (static members don't contribute to size)

Deep vs Shallow Copy

Shallow copy duplicates pointers, leading to shared resources. Deep copy allocates new memory:

class Buffer {
  int size;
  char* data;
  
public:
  Buffer(int sz) : size(sz), data(new char[sz]) {}
  
  // Deep copy constructor
  Buffer(const Buffer& src) : size(src.size), data(new char[src.size]) {
    copy(src.data, src.data + size, data);
  }
  
  ~Buffer() { delete[] data; }
};

Initialization Lists

Efficient member initialization syntax:

class Point {
  int x, y, z;
public:
  Point(int a, int b, int c) : x(a), y(b), z(c) {}
};

Object Composition

Clas members can be other objects. Construction order: member objects first, then container:

class Engine {
public:
  Engine() { cout << "Engine built" << endl; }
};

class Car {
  Engine powerplant;
public:
  Car() { cout << "Car assembled" << endl; }
};

this Pointer

Implicit pointer to current instence, enabling member access and method chaining:

class Accumulator {
  int total;
public:
  Accumulator& add(int value) {
    total += value;
    return *this;
  }
};

Accumulator acc;
acc.add(5).add(10).add(15); // Method chaining

Const Member Functions and Objects

Const member functions guarantee no state modification. Const objects can only call const methods:

class Immutable {
  mutable int modifiable; // Can be changed in const methods
  int fixed;
public:
  void modify() const { modifiable = 1; } // Const method
  void change() { fixed = 2; } // Non-const method
};

const Immutable obj;
obj.modify(); // Allowed
// obj.change(); // Error - const object cannot call non-const method

Tags: C++ Constructors destructors Static Members deep copy

Posted on Thu, 01 Oct 2026 16:59:20 +0000 by KDragon