Answered step by step
Verified Expert Solution
Question
1 Approved Answer
i got 11/50 on the code, i want some fix class MyVector { public: /******************* * Static constants ******************/ /// Default capacity static constexpr size_t
i got 11/50 on the code, i want some fix
class MyVector
{
public:
/*******************
* Static constants
******************/
/// Default capacity
static constexpr size_t DEFAULT_CAPACITY = 64;
/// Minimum capacity
static constexpr size_t MINIMUM_CAPACITY = 8;
/*****************************
* Constructors / Destructors
****************************/
/// Normal constructor
MyVector(size_t capacity = MyVector::DEFAULT_CAPACITY):
size_(0), capacity_(capacity), elements_(new T[capacity]) {
}
/// Copy constructor
MyVector(const MyVector& other) {
size_= other.size_;
capacity_= other.capacity_;
elements_= new T[capacity_];
for (size_t i = 0; i < size_; i++) {
elements_[i] = other.elements_[i];
}
}
/**
* Destructor
* Should call clear() so each element gets its destructor called.
* Then, de-allocate the internal array and make it a nullptr, if its not already a nullptr.
*/
~MyVector() {
clear();
if (elements_ != nullptr) {
delete[] elements_;
elements_ = nullptr;
size_ = 0;
capacity_ = 0;
}
}
/************
* Operators
************/
/// Assignment operator
MyVector& operator=(const MyVector& rhs) {
if (this != &rhs)
{
size_ = rhs.size_;
capacity_ = rhs.capacity_;
delete[] elements_;
elements_ = new T[capacity_];
for (size_t i = 0; i < size_; i++)
elements_[i] = rhs.elements_[i];
}
return *this;
}
/// Operator overload to at()
T& operator[](size_t index) const {
return elements_[index];
}
/************
* Accessors
************/
/// Return the number of valid elements in our data
size_t size() const {
return size_;
}
/// Return the capacity of our internal array
size_t capacity() const {
return capacity_;
}
/**
* Check whether our vector is empty
* Return true if we have zero elements in our array (regardless of capacity)
* Otherwise, return false
*/
bool empty() const {
return size_ == 0;
}
/// Return a reference to the element at an index
T& at(size_t index) const {
if (index >= size_)
throw std::out_of_range("Index out of range");
return elements_[index];
}
/***********
* Mutators
***********/
/**
* Reserve capacity in advance, if our capacity isn't currently large enough.
* Useful if we know we're about to add a large number of elements, and we'd like to avoid the overhead of many internal changes to capacity.
*/
void reserve(size_t capacity) {
if (capacity <= capacity_)
return;
capacity_ = capacity;
T* custom_elements = new T[capacity];
for (size_t i = 0; i < size_; i++)
custom_elements[i] = elements_[i];
delete[] elements_;
elements_ = custom_elements;
}
/**
* Set an element at an index.
* Throws range error if outside the size boundary.
* Returns a reference to the newly set element (not the original)
*/
T& set(size_t index, const T& element) {
if (index >= size_)
throw std::out_of_range("Index out of range");
elements_[index] = element;
return elements_[index];
}
/**
* Add an element onto the end of our vector, increasing the size by 1
* Should rely on the insert() function to avoid repeating code.
* Returns a reference to the newly inserted element
*/
T& push_back(const T& element) {
if (size_ == capacity_)
reserve(capacity_ * 2);
elements_[size_++] = element;
return elements_[size_ - 1];
}
/**
* Remove the last element in our vector, decreasing the size by 1
* Should rely on the erase() function to avoid repeating code.
* Returns the new size.
*/
size_t pop_back() {
if (empty())
throw std::out_of_range("Vector is empty");
size_--;
return size_;
}
/**
* Insert an element at some index in our vector, increasing the size by 1
*
* Scoot all elements at index and beyond, one to the right. This
* makes a "hole" available at the index, where you can then place
* the new element.
*
* Returns a reference to the newly added element (not the original).
*/
T& insert(size_t index, const T& element) {
if (index > size_)
{
throw std::range_error("Index out of bounds");
}
if (size_ == capacity_)
{
reserve(capacity_ * 2);
}
size_t i = size_;
while (i > index)
{
elements_[i] = elements_[i - 1];
i--;
}
elements_[index] = element;
size_++;
return elements_[index];
}
/**
* Erase one element in our vector at the specified index, decreasing the size by 1.
*
* This means you'd then have to scoot elements to the left to fill the "hole"
* left by the erased element.
*
* Throws std::range_error if the index is out of bounds.
*
* Calls the erased element's destructor.
*
* Returns the new size.
*/
size_t erase(size_t index) {
if (index >= size_)
{
throw std::range_error("Index out of bounds");
}
elements_[index].~T();
for (size_t i = index; i < size_ - 1; ++i) {
new (&elements_[i]) T(std::move(elements_[i + 1]));
}
--size_;
return size_;
}
/**
* Calls each element's destructor, then clears our internal
* data by setting size to zero and resetting the capacity.
*/
void clear() {
for (size_t i = 0; i < size_; ++i)
{
elements_[i].~T();
}
size_ = 0;
capacity_ = 0;
operator delete(elements_);
elements_ = nullptr;
}
/**
* Begin private members and methods.
* Private methods can often contain useful helper functions,
* or functions to reduce repeated code.
*/
private:
/// Number of valid elements currently in our vector
size_t size_ = 0;
/// Capacity of our vector; The actual size of our internal array
size_t capacity_ = 0;
/**
* Our internal array of elements of type T.
* Starts off as a null pointer.
*/
T* elements_ = nullptr;
/**
* Helper function that is called whenever we need to change the capacity of our vector
* Should throw std::range_error when asked to change to a capacity that cannot hold our existing elements.
* It's probably a good idea to make an additional helper function that decides
* whether to change capacity at all (and to what new capacity), that your public functions can rely upon.
*/
void increaseSize() {
if(size_ == capacity_) {
size_t new_capacity = capacity_ == 0 ? MINIMUM_CAPACITY : 2 * capacity_;
changeCapacity(new_capacity);
}
size_++;
}
void decreaseSize() {
if(size_ == 0) {
return;
}
size_--;
if(capacity_ > MINIMUM_CAPACITY && size_ <= capacity_ / 3) {
size_t new_capacity = capacity_ / 2;
changeCapacity(new_capacity);
}
}
void changeCapacity(size_t c) {
assertCapacity(c);
T* newElements = new T[c];
if(size_ > 0) {
copyElements(newElements, size_);
}
delete[] elements_;
elements_ = newElements;
capacity_ = c;
}
/**
* Copy another vector's elements into our own, by value.
* Does not simply copy the other vector's array's pointer
* Does not care about matching the capacity exactly.
* This is a helper function relied upon by the copy constructor and the assignment operator,
* to avoid repeated code.
*
* You will probably want to make additional helper functions to make this one easier.
* Here is a suggested strategy for copying the internal array:
* 1. Deallocate the current array for 'this' (if it is already allocated)
* 2. Allocate a new array for 'this' of the appropriate size
* 3. Use a loop to copy elements one-by-one (by value)
* 4. Copy other relevant properties from the 'other' to 'this'
*/
void copyOther(const MyVector& other) {
if(this == &other) {
return;
}
if(capacity_ < other.capacity_) {
changeCapacity(other.capacity_);
}
size_ = other.size_;
copyElements(other.elements_, size_);
}
void assertCapacity(size_t c) const {
if(capacity_ < c) {
throw std::range_error("Insufficient capacity");
}
}
void assertBounds(size_t index, std::string message = "") const {
if(index >= size_) {
if(message.empty()) {
throw std::range_error("Index out of bounds");
}
else {
throw std::range_error(message);
}
}
}
};
Here are auto-grader feedback:
Failed Tests
Grow/Shrink tests (6.0/10.0)
Range tests (0.0/5.0)
Capacity tests (0.0/5.0)
Deletion tests (0.0/5.0)
Copy tests (0.0/5.0)
Destructor tests (0.0/5.0)
Empty tests (0.0/5.0)
Pointer Stealing (0.0/5.0)
Memory Leaks (0.0/5.0)
Passed Tests
Free point test(s) (1.0/1.0)
PushBack tests (5.0/5.0)
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started