Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

IntVector class, C++ You are going to build a smaller, simpler version of the ST

ID: 3793860 • Letter: I

Question

IntVector class, C++

You are going to build a smaller, simpler version of the STL vector class that is capable of only storing integers. Appropriately, it will be called IntVector. This class will encapsulate a dynamically allocated array of integers.

You are required to come up with a header file (IntVector.h) that declares the class interface and a separate implementation file (IntVector.cpp) that implements the member functions. You will also create a test harness (main.cpp) that you use to test each function you are currently developing.

Encapsulated (Private) Data Fields

unsigned sz: stores the size of the IntVector (the number of elements currently being used).

unsigned cap: store the size of the array

int *data: stores the address of the dynamically-allocated array of integers

Public Interface (Public Member Functions)

IntVector()

IntVector(unsigned size, int value = 0)

~IntVector()

unsigned size() const

unsigned capacity() const

bool empty() const

const int & at(unsigned index) const

int & at(unsigned index)

void insert(unsigned index, int value)

void erase(unsigned index)

const int & front() const

int & front()

const int & back() const

int & back()

void assign(unsigned n, int value)

void push_back(int value)

void pop_back()

void clear()

void resize(unsigned size, int value = 0)

void reserve(unsigned n)

You may NOT add any functions to the public interface nor any member variables at all, public or private.

Private Helper Functions

void expand()

void expand(unsigned amount)

You will not be implementing iterators. On the most part, though, the above functions should work just like the STL vector class member function with the same name. Please see the following pages to get a better idea of what each function should do: STL Vector

Constructors and Accessors

IntVector() - the Default constructor

This function should set both the size and capacity of the IntVector to 0 and will not allocate any memory to store integers.
(Make sure you do not have a dangling pointer.)

IntVector(unsigned size, int value = 0)

Sets both the size and capacity of the IntVector to the value of the parameter passed in and dynamically allocates an array of that size as well. This function should initialize all elements of the array to the value of the 2nd parameter.

unsigned size() const

This function returns the current size (not the capacity) of the IntVector object, which is the values stored in the sz data field.

unsigned capacity() const

This function returns the current capacity (not the size) of the IntVector object, which is the value stored in the cap data field.

bool empty() const

Returns whether the IntVector is empty (the sz field is 0).

const int & at(unsigned index) const

This function will return the value stored in the element at the passed in index position.

This function should throw an out_of_range exception, passing it the string "IntVector::at_range_check" if the index is beyond the size of the IntVector. See bottom of specifications for more details on how to throw an exception and how to test that it works properly.

const int & front() const

This function will return the value stored in the first element.

const int & back() const

This function will return the value stored in the last element.

Destructor, Mutators, & Private Helper Functions

~IntVector()

The destructor is used to clean up (delete) any remaining dynamically-allocated memory. For this class, that will be the array pointed to by the int pointer called data.

void expand()

This function will double the capacity of the vector. This function should reallocate memory for the dynamically allocated array and update the value of capacity. Be careful to properly handle the case when capacity is 0 before calling expand().

Make sure you don't create a memory leak here.

void expand(unsigned amount)

This function will expand the capacity of the vector by the amount passed in. This function should reallocate memory for the dynamically allocated array and update the value of capacity.

Make sure you don't create a memory leak here.

void insert(unsigned index, int value)

This function inserts data at position index. To do this, all values currently at position index and greater are shifted to the right by 1 (to the element right after its current position).

Size will be increased by 1. However, If size will become larger than capacity, this function needs to first double the capacity. In other words, if capacity and size are both 20 when this function is called, this function must first increase the capacity to 40 and then it will be able to increase the size to 21.

Since other functions will also potentially need to expand (double) the capacity, call the private helper function named expand (see above) to do this for you.

This function should throw an out_of_range exception, passing it the string "IntVector::insert_range_check" if the index is too large. See bottom of specifications for more details on how to throw an exception and how to test that it works properly.

void erase(unsigned index)

This function removes the value at position index and shifts all of the values at positions greater than index to the left by one (to the element right before its current position).

Size is decreased by 1.

This function should throw an out_of_range exception, passing it the string "IntVector::erase_range_check" if the index is too large. See bottom of specifications for more details on how to throw an exception and how to test that it works properly.

void push_back(int value)

This function inserts a value at the back end of the array.

Size will be increased by 1. However, If size will become larger than capacity, this function needs to first increase the capacity. In other words, if capacity and size are both 20 when this function is called, capacity must first be increased to 40 and then size can be increased to 21.

Since other functions will also potentially need to expand (double) the capacity, call the private helper function named expand (see above) to do this for you.

void pop_back()

This function just needs to decrease size by 1.

This function will never thrown an exception. Calling pop_back on an empty vector will cause undefined behavior.

void clear()

This function reduces the size of the vector to 0.

void resize(unsigned size, int value = 0)

This function resizes the vector to contain size elements.

If size is smaller than the current size(sz), this function just reduces the value of sz to size.

If size is greater than the current size(sz), then the appropriate number of elements are inserted at the end of the vector, giving all of the new elements the value passed in through the 2nd parameter (value).

If the new value of size will be larger than capacity, then the capacity must first be expanded by either doubling (expand()) or by increasing the capacity by a specific amount (expand(size - cap)), whichever results in the largest capacity. Then, this function can then increase the size appropriately.

void reserve(unsigned n)

This function requests that the capacity (the size of the dynamically allocated array) be set to n at minimum. This informs the vector of a planned increase in size, although notice that the parameter n informs of a minimum, so the resulting capacity may be any capacity equal or larger than this.

This function should NOT ever reduce the size of the vector. If n is larger than the current capacity then the capacity should be expanded by either doubling (expand()) or by increasing the capacity by a specific amount (expand(n - cap)), whichever results in the largest capacity.

In any case, a call to this function never affects the elements contained in the vector, nor the vector size.

void assign(unsigned n, int value)

Assigns new content to the vector object, dropping all the elements contained in the vector before the call and replacing them by those specified by the parameters. The new value of size will be n and all values stored in the vector will have the value of the 2nd parameter.

If the new value of size will be larger than capacity, then this function must first expand capacity by either double (expand()) or by increasing the capacity by a specific amount (expand(n - cap)), whichever results in the largest capacity.

int & at(unsigned index)

This function does exactly the same thing the accessor (const) version of at does.

int & front( )

This function does exactly the same thing the accessor (const) version of front does.

int & back( )

This function does exactly the same thing the accessor (const) version of back does.

Throwing an exception

You will need to include the standard library stdexcept. Then, when the index is out of range, execute the following statement:

To test if this worked, declare an IntVector of size 10 and then call the at function passing it an index argument of 10 or larger. You should see the following output:

Explanation / Answer

Given below are the files needed for the question. Output is shown in the end. Please don't forget to rate the answer if it helped. Thank you.

IntVector.h

#ifndef IntVector_h
#define IntVector_h
class IntVector
{
  
private:
unsigned sz;
unsigned cap;
int *data;
void expand();
void expand(unsigned amount);
public:
IntVector();
IntVector(unsigned size, int value = 0);
~IntVector();
unsigned size() const;
unsigned capacity() const;
bool empty() const;
const int & at(unsigned index) const;
int & at(unsigned index);
void insert(unsigned index, int value);
void erase(unsigned index);
const int & front() const;
int & front();
const int & back() const;
int & back();
void assign(unsigned n, int value);
void push_back(int value);
void pop_back();
void clear();
void resize(unsigned size, int value = 0);
void reserve(unsigned n);
  
};

#endif /* IntVector_h */

IntVector.cpp

#include "IntVector.h"
#include <stdexcept>
using namespace std;
IntVector::IntVector()
{
sz = 0;
cap = 0;
data = nullptr;
}
IntVector::IntVector(unsigned size, int value)
{
sz = cap = size;
data = new int[size];
//initialize all elements to value
for(int i = 0; i < size; i++)
data[i] = value;
}

IntVector::~IntVector()
{
if(data != nullptr)
delete []data;
}
unsigned IntVector::size() const
{
return sz;
}
unsigned IntVector::capacity() const
{
return cap;
}
bool IntVector::empty() const
{
return sz == 0;
}
const int & IntVector::at(unsigned index) const
{
if(index < 0 || index >= sz)
throw out_of_range("IntVector::at_range_check");
return data[index];
}
int & IntVector::at(unsigned index)
{
if(index < 0 || index >= sz)
throw out_of_range("IntVector::at_range_check");
return data[index];
}
void IntVector::insert(unsigned index, int value)
{
if(index < 0 || index >= sz)
throw out_of_range("IntVector::insert_range_check");
  
if(sz == cap)
expand();
for(int i = sz; i > index; i--)
data[i] = data[i-1];
data[index] = value;
sz++;
}
void IntVector::erase(unsigned index)
{
if(index < 0 || index >= sz)
throw out_of_range("IntVector::erase_range_check");
  
  
for(int i = index; i < sz - 1; i++)
data[i] = data[i+1];
  
sz--;
}
const int & IntVector::front() const
{
if(empty())
throw runtime_error("IntVector::front_empty_check");
return data[0];
}
int & IntVector::front()
{
if(empty())
throw runtime_error("IntVector::front_empty_check");
return data[0];
}
const int & IntVector::back() const
{
if(empty())
throw runtime_error("IntVector::back_empty_check");
return data[sz - 1];
}
int & IntVector::back()
{
if(empty())
throw runtime_error("IntVector::back_empty_check");
return data[sz - 1];
}

void IntVector::assign(unsigned n, int value)
{
reserve(n);
sz = n;
for(int i = 0; i < sz; i++)
data[i] = value;
}

void IntVector::push_back(int value)
{
if(sz == cap)
expand();
data[sz] = value;
sz++;
}
void IntVector::pop_back()
{
if(!empty())
sz--;
}
void IntVector::clear()
{
sz = 0;
}
void IntVector::resize(unsigned size, int value)
{
if(size > sz)
{
reserve(size);
for(int i = sz; i < size; i++)
data[i] = value;
}
sz = size;
}
void IntVector::reserve(unsigned n)
{
if(n > cap)
{
int needed = n - cap;
if(needed < cap)
needed = cap;
expand(needed);
}
}
void IntVector::expand()
{
if(cap == 0)
expand(1);
else
expand(cap);
}
void IntVector::expand(unsigned amount)
{
cap += amount;
int *temp = new int[cap];
for(int i = 0; i < sz; i++)
temp[i] = data[i];
if(data != nullptr)
delete []data;
data = temp;
}

IntVectorMain.cpp

#include "IntVector.h"
#include <iostream>
using namespace std;
void display(const IntVector &v);
int main()
{
IntVector v1;
IntVector v2(3, 1);
  
cout << "created v1 with default constructor" << endl;
cout << "created v2 with parameterized constructor of capacity 3 and values 1" << endl;
cout << "v1: sz = " << v1.size() << " cap = " << v1.capacity() << endl;
cout << "v2: sz = " << v2.size() << " cap = " << v2.capacity() << endl;
cout << "v1: "; display(v1);
cout << "v2: "; display(v2);
cout << "v2: assigning 5 to front and 10 to back" << endl;
v2.front() = 5;
v2.back() = 10;
cout << "v2: "; display(v2);
cout << "v1: resized to 5, value = 2" << endl;
v1.resize(5, 2);
cout << "v1: sz = " << v1.size() << " cap = " << v1.capacity() << endl;
cout << "v1: "; display(v1);
  
cout << "v2: resized to 10, value = 0" << endl;
v2.resize(10, 0);
cout << "v2: sz = " << v2.size() << " cap = " << v2.capacity() << endl;
cout << "v2: "; display(v2);
  
cout << "v2: assign size to 5, value = -1" << endl;
v2.assign(5, -1);
cout << "v2: sz = " << v2.size() << " cap = " << v2.capacity() << endl;
cout << "v2: "; display(v2);
  
cout << "v2: reserving 12 slots" << endl;
v2.reserve(12);
cout << "v2: sz = " << v2.size() << " cap = " << v2.capacity() << endl;
cout << "v2: "; display(v2);
  
cout << "v2: push_back 25" << endl;
v2.push_back(25);
cout << "v2: "; display(v2);
  
cout << "v2: clear" << endl;
v2.clear();
cout << "v2: "; display(v2);
  
cout << "v2: push back values 1-5";
for(int i = 1; i <= 5; i++)
v2.push_back(i * 2);
cout << "v2: "; display(v2);
  
cout << "v2: erase(3)" << endl;
v2.erase(3);
cout << "v2: "; display(v2);
  
cout << "v2: insert at 2 , value 30" << endl;
v2.insert(2, 30);
cout << "v2: "; display(v2);
  
  
  
}

void display(const IntVector &v)
{
for(int i = 0; i < v.size(); i++)
cout << v.at(i) << " " ;
cout << endl;
}

output

created v1 with default constructor
created v2 with parameterized constructor of capacity 3 and values 1
v1: sz = 0 cap = 0
v2: sz = 3 cap = 3
v1:
v2: 1 1 1
v2: assigning 5 to front and 10 to back
v2: 5 1 10
v1: resized to 5, value = 2
v1: sz = 5 cap = 5
v1: 2 2 2 2 2
v2: resized to 10, value = 0
v2: sz = 10 cap = 10
v2: 5 1 10 0 0 0 0 0 0 0
v2: assign size to 5, value = -1
v2: sz = 5 cap = 10
v2: -1 -1 -1 -1 -1
v2: reserving 12 slots
v2: sz = 5 cap = 20
v2: -1 -1 -1 -1 -1
v2: push_back 25
v2: -1 -1 -1 -1 -1 25
v2: clear
v2:
v2: push back values 1-5v2: 2 4 6 8 10
v2: erase(3)
v2: 2 4 6 10
v2: insert at 2 , value 30
v2: 2 4 30 6 10

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote