Object-Oriented Programming
Constructors
Default, parameterized, and copy constructors
Interview: Object initialization
Constructors
Constructors initialize objects. They are called automatically when an object is created. A class can have multiple constructors (overloaded) for different initialization scenarios. Constructors have the same name as the class and no return type.
Types of Constructors
- Default constructor: No parameters. Required for default-constructing arrays of objects and STL containers.
- Parameterized constructor: Takes arguments to set initial state.
- Copy constructor:
Foo(const Foo& other)— initializes from another object of same type. - Move constructor:
Foo(Foo&& other)— transfers resources from a temporary (C++11). - Delegating constructor: A constructor that calls another constructor in its initializer list (C++11).
explicit Keyword
Marking a single-argument constructor explicit prevents implicit conversions. Without explicit, Foo f = 5; would silently call Foo(int). This accidental conversion can cause subtle bugs and is almost always unintended.
Interview Corner
Q: What is the Most Vexing Parse?
A: Foo f(Bar()) — the programmer intends to create a Foo initialized with a Bar object, but C++ parses this as a function declaration (f takes a pointer to a function returning Bar, and returns Foo). Fix: use brace initialization Foo f{Bar{}} or assign: Foo f = Foo(Bar()).
Q: Why should single-argument constructors be marked explicit?
A: Without explicit, the compiler performs implicit conversions. For example, a string(int) constructor would allow string s = 42; — creating a string with 42 characters rather than "42". explicit forces callers to be intentional: string s(42).
Common Pitfalls
- Initializing members in the wrong order: Members are initialized in declaration order, not initializer list order. Writing the list in a different order is confusing and may cause bugs if members depend on each other.
- Forgetting explicit: Single-argument constructors without explicit participate in implicit conversions, often unintentionally.
Best Practices
- Mark all single-argument constructors
explicitby default. Only remove explicit when implicit conversion is intentionally desired. - Use member initializer lists for all member initialization, not assignment in the constructor body.