Implement a Unique Pointer and Vector
Problem Description
You are tasked with implementing simplified versions of two fundamental C++ standard library abstractions: std::unique_ptr and std::vector. You must achieve this without utilizing the actual std::unique_ptr or std::vector classes internally.
Part 1: Implement UniquePtr<T>
Design and implement a class UniquePtr<T> that models exclusive ownership of a dynamically allocated object.
Requirements:
- Ownership: Must own exactly one dynamically allocated object of type
T. - Resource Release: The owned object must be deleted in the destructor (Resource Acquisition Is Initialization - RAII).
- Core Functionality: Support the following member functions and operators:
- Default constructor (creates an empty
UniquePtr). - Constructor from a raw pointer (takes ownership).
get(): Returns the raw pointer to the owned object.release(): Relinquishes ownership and returns the raw pointer, setting theUniquePtrto empty.reset(): Destroys the currently owned object (if any) and takes ownership of a new raw pointer (or becomes empty).operator*: Dereferences the owned object.operator->: Provides member access to the owned object.- Conversion to
bool: Evaluates totrueif an object is owned,falseotherwise.
- Default constructor (creates an empty
- Copy Semantics: Explicitly disable copy construction and copy assignment to enforce unique ownership.
- Move Semantics: Support move construction and move assignment to transfer ownership efficiently.
- Self-Assignment: Ensure move assignment handles self-assignment safely.
Part 2: Implement SimpleVector<T>
Design and implement a class SimpleVector<T> that models a dynamic array, storing elements contiguously.
Requirements:
- Storage: Elements must be stored contiguously in memory.
- Size and Capacity: Track and provide
size()(number of elements) andcapacity()(total allocated storage). - Core Functionality: Support the following member functions and operators:
- Default constructor.
- Destructor.
- Copy constructor.
- Copy assignment operator.
- Move constructor.
- Move assignment operator.
push_back(const T& value): Adds an element to the end, growing capacity if necessary.pop_back(): Removes the last element.operator[](size_t index): Provides access to elements by index.reserve(size_t new_capacity): Increases the capacity to at leastnew_capacity.clear(): Removes all elements, leaving capacity unchanged.
- Element Management: Correctly construct and destroy elements, especially for non-POD types.
- Dynamic Growth: Automatically grow capacity when
push_backrequires more space than currently available.
Follow-up Question
Explain the fundamental difference between copy semantics and move semantics in C++. Subsequently, describe where and why each of these semantic types is employed within your implementations of UniquePtr<T> and SimpleVector<T>.
AI interview prep
Core dilemma
Implementing robust and efficient resource management in C++ from first principles, balancing raw memory manipulation with idiomatic C++ features like RAII, move semantics, and exception safety.
3 tradeoffs and 3 stress tests locked
Interview prep
Unlock the interviewer X-Ray rubric, tradeoff matrix, stress tests, clarifying questions, and key concepts.
Implement a Unique Pointer and Vector
Problem Description
You are tasked with implementing simplified versions of two fundamental C++ standard library abstractions: std::unique_ptr and std::vector. You must achieve this without utilizing the actual std::unique_ptr or std::vector classes internally.
Part 1: Implement UniquePtr<T>
Design and implement a class UniquePtr<T> that models exclusive ownership of a dynamically allocated object.
Requirements:
- Ownership: Must own exactly one dynamically allocated object of type
T. - Resource Release: The owned object must be deleted in the destructor (Resource Acquisition Is Initialization - RAII).
- Core Functionality: Support the following member functions and operators:
- Default constructor (creates an empty
UniquePtr). - Constructor from a raw pointer (takes ownership).
get(): Returns the raw pointer to the owned object.release(): Relinquishes ownership and returns the raw pointer, setting theUniquePtrto empty.reset(): Destroys the currently owned object (if any) and takes ownership of a new raw pointer (or becomes empty).operator*: Dereferences the owned object.operator->: Provides member access to the owned object.- Conversion to
bool: Evaluates totrueif an object is owned,falseotherwise.
- Default constructor (creates an empty
- Copy Semantics: Explicitly disable copy construction and copy assignment to enforce unique ownership.
- Move Semantics: Support move construction and move assignment to transfer ownership efficiently.
- Self-Assignment: Ensure move assignment handles self-assignment safely.
Part 2: Implement SimpleVector<T>
Design and implement a class SimpleVector<T> that models a dynamic array, storing elements contiguously.
Requirements:
- Storage: Elements must be stored contiguously in memory.
- Size and Capacity: Track and provide
size()(number of elements) andcapacity()(total allocated storage). - Core Functionality: Support the following member functions and operators:
- Default constructor.
- Destructor.
- Copy constructor.
- Copy assignment operator.
- Move constructor.
- Move assignment operator.
push_back(const T& value): Adds an element to the end, growing capacity if necessary.pop_back(): Removes the last element.operator[](size_t index): Provides access to elements by index.reserve(size_t new_capacity): Increases the capacity to at leastnew_capacity.clear(): Removes all elements, leaving capacity unchanged.
- Element Management: Correctly construct and destroy elements, especially for non-POD types.
- Dynamic Growth: Automatically grow capacity when
push_backrequires more space than currently available.
Follow-up Question
Explain the fundamental difference between copy semantics and move semantics in C++. Subsequently, describe where and why each of these semantic types is employed within your implementations of UniquePtr<T> and SimpleVector<T>.