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

I need help with the following program: I need to Convert the int_vector class t

ID: 3890558 • Letter: I

Question

I need help with the following program:

I need to Convert the int_vector class to a templated class, and make the class expandable and contractible. Also, I need to add error checking to the operator[] so that the index is not allowed to exceed or equal the size of the vector.

//

// main.cpp

// int_vector_class

//

//

#include <iostream>

#include <string>

#include <initializer_list>

#include <exception>

using namespace std;

class int_vector {

public:

//constructor

int_vector()

: capacity_(minCapacity_), size_(0), data_(new int[capacity_]) {

cout << "c'ting... " << this << " ";

}

//new constructor

int_vector(const std::initializer_list<int>& li) : int_vector() {

for (int i : li) {

*(data_ + size_++) = i;

}

cout << "...std::initializer_list<int> c'ting... " << this << " ";

}

//copy constructor

int_vector(const int_vector& other) : data_(nullptr) {

copy(other);

cout << "copy c'ting... " << this << " ";

};

//assignment operator

int_vector& operator=(const int_vector& other) {

if (this != &other) { copy(other); }

return *this;

};

//destructor

~int_vector() {

cout << "deleting: " << this << " ";

delete[] data_;

}

  

void push_back(int value) {

check_empty();

data_[size_++] = value;

}

void pop_back() {

check_empty();

data_[size_--] = 0;

}

  

int front() const {

check_empty();

return data_[0];

}

  

int back() const {

check_empty();

return data_[size_ - 1];

}

  

  

size_t size() const { return size_; }

bool empty() const { return size_ == 0; }

  

  

int operator[](size_t index) const { return data_[index]; }

int& operator[](size_t index) { return data_[index]; }

  

  

friend std::ostream& operator<<(std::ostream& os, const int_vector& iv) {

if (iv.size_ == 0) { return os << "<empty>"; }

  

os << "int_vector[size=" << iv.size_ << ", data=";

for (int i = 0; i < iv.size_; ++i) {

os << *(iv.data_ + i) << " ";

}

return os << "]";

}

  

private:

  

void copy(const int_vector& other) {

if (data_ != nullptr) {

delete[] data_;

}

capacity_ = other.capacity_;

size_ = other.size_;

data_ = new int[size_];

memcpy(data_, other.data_, size_ * sizeof(int));

  

}

  

void check_empty() const {

if (size_ == 0) {

throw new std::invalid_argument("size is empty");

}

};

  

void check_overflow() const {

if (size_ == capacity_)

throw new std::invalid_argument("data is greater than capacity");

};

//same as constructor

const int minCapacity_ = 10;

size_t capacity_;

size_t size_;

int* data_;

  

};

int main() {

  

int_vector ivdefault;

int_vector iv2({ 3, 1, 4, 1, 5, 9, 2, 6, 5 });

int_vector ivcopycted = iv2;

ivdefault = iv2;

  

iv2[0] = 2;

iv2[1] = 7;

iv2[2] = 1;

  

cout << " iv[0] is: " << iv2[0] << " ";

cout << "front of iv2 is: " << iv2.front() << endl;

cout << "back of iv2 is: " << iv2.back() << endl;

cout << "size of iv2 is: " << iv2.size() << " ";

  

cout << "ivdefault is: " << ivdefault << endl;

cout << "iv2 is: " << iv2 << endl;

cout << "ivcopycted is: " << ivcopycted << endl;

  

//iv2.push_back(100);

//iv2.push_back(101); //will cause an exception to be thrown

  

while (!iv2.empty()) { iv2.pop_back(); }

cout << " iv2 is now: " << iv2 << " ";

  

//iv2.pop_back(); //will cause an exception to be thrown

  

cout << " ...done." << endl;

return 0;

  

  

}

Explanation / Answer

Given below is the modified code - output is shown. Since the class now is template, calling it int_vector does not make sense, since it can take any type. So renamed it to myvector.

Hope the answer helped. If it did, please don't forget to rate it. Thank you.

//
// main.cpp
// int_vector_class
//
//

#include <iostream>
#include <string>
#include <initializer_list>
#include <exception>
using namespace std;

template <typename T>
class myvector {
public:
//constructor
myvector()
: capacity_(minCapacity_), size_(0), data_(new int[capacity_]) {
cout << "c'ting... " << this << " ";
}
//new constructor
myvector(const std::initializer_list<T>& li) : myvector() {
for (int i : li) {
*(data_ + size_++) = i;
}
cout << "...std::initializer_list<int> c'ting... " << this << " ";
}
//copy constructor
myvector(const myvector<T>& other) : data_(nullptr) {
copy(other);
cout << "copy c'ting... " << this << " ";
};
//assignment operator
myvector<T>& operator=(const myvector<T>& other) {
if (this != &other) { copy(other); }
return *this;
};
//destructor
~myvector() {
cout << "deleting: " << this << " ";
delete[] data_;
}
  
void push_back(T value) {
check_overflow();
data_[size_++] = value;
}
void pop_back() {
check_empty();
data_[size_--] = 0;
shrink_if_needed();
}
  
T front() const {
check_empty();
return data_[0];
}
  
T back() const {
check_empty();
return data_[size_ - 1];
}
  
  
size_t size() const { return size_; }
bool empty() const { return size_ == 0; }
  
  
  
T operator[](size_t index) const {
check_index(index);
return data_[index];
}
T& operator[](size_t index) {
check_index(index);
return data_[index];
}
  
  
friend std::ostream& operator<<(std::ostream& os, const myvector<T>& iv) {
if (iv.size_ == 0) { return os << "<empty>"; }
  
os << "int_vector[size=" << iv.size_ << ", data=";
for (int i = 0; i < iv.size_; ++i) {
os << *(iv.data_ + i) << " ";
}
return os << "]";
}
  
private:
  
void copy(const myvector<T>& other) {
if (data_ != nullptr) {
delete[] data_;
}
capacity_ = other.capacity_;
size_ = other.size_;
data_ = new int[size_];
memcpy(data_, other.data_, size_ * sizeof(int));
  
}
  
void check_empty() const {
if (size_ == 0) {
throw new std::invalid_argument("size is empty");
}
};
  
void check_index(int index) const {
if (index < 0 || index >= size_) {
throw new std::invalid_argument("invalid index");
}
};
  
void check_overflow() {
if (size_ == capacity_)
{
capacity_ *= 2;//double the capacity
T *temp = new T[capacity_];
memcpy(temp, data_, size_ * sizeof(T)); //copy all the data
delete[] data_; //deallocate old memory
data_ = temp; //use new memory
}
};
  
void shrink_if_needed()
{
if(size_ < capacity_ / 4) //if only 25% of the whole array is occupied, shrink to 1/2 capacity
{
capacity_ /= 2;
T *temp = new T[capacity_];
memcpy(temp, data_, size_ * sizeof(T)); //copy all the data
delete[] data_; //deallocate old memory
data_ = temp; //use new memory
}
}
//same as constructor
const int minCapacity_ = 10;
size_t capacity_;
size_t size_;
T* data_;
  
};


int main() {
  
myvector<int> ivdefault;
myvector<int> iv2({ 3, 1, 4, 1, 5, 9, 2, 6, 5 });
myvector<int> ivcopycted = iv2;
ivdefault = iv2;
  
iv2[0] = 2;
iv2[1] = 7;
iv2[2] = 1;
  
cout << " iv[0] is: " << iv2[0] << " ";
cout << "front of iv2 is: " << iv2.front() << endl;
cout << "back of iv2 is: " << iv2.back() << endl;
cout << "size of iv2 is: " << iv2.size() << " ";
  
cout << "ivdefault is: " << ivdefault << endl;
cout << "iv2 is: " << iv2 << endl;
cout << "ivcopycted is: " << ivcopycted << endl;
  
iv2.push_back(100);
iv2.push_back(101); //should expand
iv2.push_back(102);
iv2.push_back(103);
cout << "iv2 is: " << iv2 << endl;
  
iv2[3] = 30;
cout << "changing iv2[3] = 30" << endl;
cout << "iv2 is: " << iv2 << endl;

  
while (!iv2.empty()) { iv2.pop_back(); }
cout << " iv2 is now: " << iv2 << " ";
  
//iv2.pop_back(); //will cause an exception to be thrown
  
//cout << iv2[20] << endl; //will cause exception since index out of range
  
cout << " ...done." << endl;
return 0;
  
  
}

output


c'ting... 0x7fff5fbff5d8
c'ting... 0x7fff5fbff5b8
...std::initializer_list<int> c'ting... 0x7fff5fbff5b8
copy c'ting... 0x7fff5fbff578
iv[0] is: 2
front of iv2 is: 2
back of iv2 is: 5
size of iv2 is: 9
ivdefault is: int_vector[size=9, data=3 1 4 1 5 9 2 6 5 ]
iv2 is: int_vector[size=9, data=2 7 1 1 5 9 2 6 5 ]
ivcopycted is: int_vector[size=9, data=3 1 4 1 5 9 2 6 5 ]
iv2 is: int_vector[size=13, data=2 7 1 1 5 9 2 6 5 100 101 102 103 ]
changing iv2[3] = 30
iv2 is: int_vector[size=13, data=2 7 1 30 5 9 2 6 5 100 101 102 103 ]
iv2 is now: <empty>
...done.
deleting: 0x7fff5fbff578
deleting: 0x7fff5fbff5b8
deleting: 0x7fff5fbff5d8