Constructors are special member functions automatically invoked when an object is created. They share the name of the class and have no return type. A default constructor is one that can be called with no arguments; the compiler generates one only if no other constructor is declared, and you can force its creation with = default. A parameterized constructor accepts arguments used to initialize member variables, and a copy constructor initializes a new object as a copy of an existing one, taking a const reference to the class type, and is invoked when passing or returning by value or when explicitly initializing one object from another. A delegating constructor calls another constructor of the same class from its initializer list to avoid code duplication, and a conversion constructor is a non-explicit single-argument constructor that permits implicit conversion from its argument type to the class type, which can be blocked by marking it explicit.
Initialization is preferred over assignment inside the constructor body. The member initializer list, written after a colon following the constructor parameter list, initializes members before the constructor body runs and is required for const members, references, and base class subobjects. Default member initializers specified at the declaration site, such as int count = 0, supply a default value whenever the constructor's initializer list omits that member. The destructor, named with a leading tilde, runs when an object's lifetime ends to release resources, and is called automatically when stack objects go out of scope or when heap objects are deleted. The Rule of Five states that if a class defines any of the destructor, copy constructor, copy assignment, move constructor, or move assignment, it should define all five to keep resource management correct. The Rule of Zero recommends the opposite: if the class uses only RAII types such as smart pointers and standard containers for its resources, the compiler-generated defaults suffice and no special members need to be written by hand.
RAII, which stands for Resource Acquisition Is Initialization, ties resource lifetime to object lifetime: resources are acquired in the constructor and released in the destructor, guaranteeing cleanup even when exceptions occur. Smart pointers are the canonical RAII wrappers for dynamic memory. std::unique_ptr provides exclusive ownership and cannot be copied, only moved, deleting the managed object when the smart pointer goes out of scope. std::shared_ptr allows shared ownership via reference counting, deleting the managed object when the last shared_ptr is destroyed, with use_count exposing the current count. std::weak_ptr is a non-owning reference to a shared_ptr-managed object that does not increment the reference count, used to break circular references and accessed through lock to obtain a temporary shared_ptr. A shallow copy duplicates pointer values but not what they point to, leaving two objects sharing the same memory, while a deep copy duplicates the pointed-to data so each object owns an independent copy, which is necessary when a class manages raw dynamic memory.
Move semantics enable the transfer of resources from one object to another without copying, dramatically improving performance for temporaries. The mechanism relies on rvalue references, written with double ampersand, which bind to temporary objects and let functions steal their internals. std::move is not a runtime operation but a cast that converts an lvalue into an rvalue reference, signaling that the source may be moved from and leaving the source in a valid but unspecified state. A forwarding reference, written as T&& in a deduced template context, binds to both lvalues (becoming T&) and rvalues (becoming T), and std::forward<T>(arg) preserves the original value category, enabling perfect forwarding into another function with no extra copies. std::swap exchanges two objects in constant time via move semantics, and the copy-and-swap idiom implements assignment by copying the source and swapping with *this, providing strong exception safety and reusing the copy and move logic. References themselves come in two forms: a plain reference is an alias for a named object that cannot be null or be reseated, while a const reference can bind to temporaries as well as named objects and is the standard way to pass large objects to functions without copying.