Write a class named MyVector using the following UML diagram and class attribute
ID: 3877895 • Letter: W
Question
Write a class named MyVector using the following UML diagram and class attribute descriptions. MyVector will use a partially filled array to store a collection of integers. The array will be created using dynamic memory allocation.
UML Diagram:
Class Attributes:
Variables:
list - an integer pointer. Holds the memory address for an integer array.
max_size - an integer that holds the capacity of the array.
list_size - an integer that stores the number of valid values currently stored in the array. The valid values in the array start at element 0 and go through list_size - 1.
Methods:
constructor - dynamically allocates the array of integers, storing it's memory address in pointer list. Initializes max_size to 10 and list_size to 0.
destructor - deletes the array.
push_back - If the array isn't full, assigns it's argument to list[list_size] and then increments list_size. The array is full if list_size == max_size.
pop_back - if the array isn't empty (list_size == 0), decrements size.
at - uses it's argument as a subscript for the array. Returns that element. It's return type is an integer reference (int&).
clear - sets list_size to 0. That's it. This effectively "empties" the array. Note, nothing about the array itself changes.
size - returns the list_size variable.
None of the above methods interacts with the user in any way.
Demonstrate your class in a program that does the following:
Uses push_back method to add ten random numbers to a MyVector object.
Uses the size method to display the number values in the object.
Calls the at method ten times to display the contents of the object.
Uses the at method to change the 3rd value in the object to 99.
Uses the pop_back method to remove the last value in the object.
Calls the at method nine times to display the changed contents of the object.
A 10-Point Sample Run:
Hints:
Review Chapter 7: "Partially filled arrays" and Vectors.
Create the array dynamically by having the following statement in the constructor:
list = new int[max_size];
Submission Instructions:
Submit your solution using three files: pc13.cpp, MyVector.h and MyVector.cpp.
MyVector.h will contain the class declaration. MyVector.cpp will contain the method definitions. pc13.cpp will #include "MyVector.h" and contain the logic of the program.
Attach the files so they look like this in blackboard:
Part 2
For this assignment you will add a copy constructor and the following overloaded operators to your MyVector class: <, ==, =, +, <<, [], and ++.
Here's a description of how each operator should behave:
operator< :
returns true if the length of the left-hand side MyVector is less than the length of the right-hand side MyVector, false otherwise.
operator== :
returns true if both MyVectors contain the exact same values, false otherwise.
operator= :
overwrites the contents of the left-hand side MyVector with the contents of the right-hand side MyVector.
operator+ :
returns a MyVector object that contains an element-by-element sum of the two operators. Consider the following snippet:
MyVector m, n;
cout << m + n;
If m contains the values 1, 2, 3 and n contains the values 4, 5, then the output would be:
[5, 7, 3].
operator<< :
sends a string representation of the MyVector object to the output stream. For example, if the MyVector contains 8 6 7, then operator<< would return [8, 6, 7] so that if you had a statement like
MyVector m;
...
cout << m;
You would see
[8, 6, 7]
on the screen.
operator++:
post-fix version. increments each element by 1. Returns a MyVector object.
operator[]:
allows for retrieving and changing elements of the MyVector.
Test your class using the attached test driver. Submit only your MyVector.h and MyVector.cpp files.
Explanation / Answer
MyVector.h
#ifndef __COMMON_VECTOR_H
#define __COMMON_VECTOR_H
#include "Defs.h"
class CBaseRecordVector
{
void MoveItems(int destIndex, int srcIndex);
protected:
int _capacity;
int _size;
void *_items;
size_t _itemSize;
void ReserveOnePosition();
void InsertOneItem(int index);
void TestIndexAndCorrectNum(int index, int &num) const
{ if (index + num > _size) num = _size - index; }
public:
CBaseRecordVector(size_t itemSize): _capacity(0), _size(0), _items(0), _itemSize(itemSize) {}
virtual ~CBaseRecordVector();
void ClearAndFree();
int Size() const { return _size; }
bool IsEmpty() const { return (_size == 0); }
void Reserve(int newCapacity);
void ReserveDown();
virtual void Delete(int index, int num = 1);
void Clear();
void DeleteFrom(int index);
void DeleteBack();
};
template <class T>
class CRecordVector: public CBaseRecordVector
{
public:
CRecordVector(): CBaseRecordVector(sizeof(T)){};
CRecordVector(const CRecordVector &v): CBaseRecordVector(sizeof(T)) { *this = v; }
CRecordVector& operator=(const CRecordVector &v)
{
Clear();
return (*this += v);
}
CRecordVector& operator+=(const CRecordVector &v)
{
int size = v.Size();
Reserve(Size() + size);
for (int i = 0; i < size; i++)
Add(v[i]);
return *this;
}
int Add(T item)
{
ReserveOnePosition();
((T *)_items)[_size] = item;
return _size++;
}
void Insert(int index, T item)
{
InsertOneItem(index);
((T *)_items)[index] = item;
}
// T* GetPointer() const { return (T*)_items; }
// operator const T *() const { return _items; };
const T& operator[](int index) const { return ((T *)_items)[index]; }
T& operator[](int index) { return ((T *)_items)[index]; }
const T& Front() const { return operator[](0); }
T& Front() { return operator[](0); }
const T& Back() const { return operator[](_size - 1); }
T& Back() { return operator[](_size - 1); }
void Swap(int i, int j)
{
T temp = operator[](i);
operator[](i) = operator[](j);
operator[](j) = temp;
}
int FindInSorted(const T& item, int left, int right) const
{
while (left != right)
{
int mid = (left + right) / 2;
const T& midValue = (*this)[mid];
if (item == midValue)
return mid;
if (item < midValue)
right = mid;
else
left = mid + 1;
}
return -1;
}
int FindInSorted(const T& item) const
{
int left = 0, right = Size();
while (left != right)
{
int mid = (left + right) / 2;
const T& midValue = (*this)[mid];
if (item == midValue)
return mid;
if (item < midValue)
right = mid;
else
left = mid + 1;
}
return -1;
}
int AddToUniqueSorted(const T& item)
{
int left = 0, right = Size();
while (left != right)
{
int mid = (left + right) / 2;
const T& midValue = (*this)[mid];
if (item == midValue)
return mid;
if (item < midValue)
right = mid;
else
left = mid + 1;
}
Insert(right, item);
return right;
}
static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param)
{
T temp = p[k];
for (;;)
{
int s = (k << 1);
if (s > size)
break;
if (s < size && compare(p + s + 1, p + s, param) > 0)
s++;
if (compare(&temp, p + s, param) >= 0)
break;
p[k] = p[s];
k = s;
}
p[k] = temp;
}
void Sort(int (*compare)(const T*, const T*, void *), void *param)
{
int size = _size;
if (size <= 1)
return;
T* p = (&Front()) - 1;
{
int i = size / 2;
do
SortRefDown(p, i, size, compare, param);
while (--i != 0);
}
do
{
T temp = p[size];
p[size--] = p[1];
p[1] = temp;
SortRefDown(p, 1, size, compare, param);
}
while (size > 1);
}
};
typedef CRecordVector<int> CIntVector;
typedef CRecordVector<unsigned int> CUIntVector;
typedef CRecordVector<bool> CBoolVector;
typedef CRecordVector<unsigned char> CByteVector;
typedef CRecordVector<void *> CPointerVector;
template <class T>
class CObjectVector: public CPointerVector
{
public:
CObjectVector() {};
~CObjectVector() { Clear(); };
CObjectVector(const CObjectVector &v): CPointerVector() { *this = v; }
CObjectVector& operator=(const CObjectVector &v)
{
Clear();
return (*this += v);
}
CObjectVector& operator+=(const CObjectVector &v)
{
int size = v.Size();
Reserve(Size() + size);
for (int i = 0; i < size; i++)
Add(v[i]);
return *this;
}
const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
T& Front() { return operator[](0); }
const T& Front() const { return operator[](0); }
T& Back() { return operator[](_size - 1); }
const T& Back() const { return operator[](_size - 1); }
int Add(const T& item) { return CPointerVector::Add(new T(item)); }
void Insert(int index, const T& item) { CPointerVector::Insert(index, new T(item)); }
virtual void Delete(int index, int num = 1)
{
TestIndexAndCorrectNum(index, num);
for (int i = 0; i < num; i++)
delete (T *)(((void **)_items)[index + i]);
CPointerVector::Delete(index, num);
}
int Find(const T& item) const
{
for (int i = 0; i < Size(); i++)
if (item == (*this)[i])
return i;
return -1;
}
int FindInSorted(const T& item) const
{
int left = 0, right = Size();
while (left != right)
{
int mid = (left + right) / 2;
const T& midValue = (*this)[mid];
if (item == midValue)
return mid;
if (item < midValue)
right = mid;
else
left = mid + 1;
}
return -1;
}
int AddToSorted(const T& item)
{
int left = 0, right = Size();
while (left != right)
{
int mid = (left + right) / 2;
const T& midValue = (*this)[mid];
if (item == midValue)
{
right = mid + 1;
break;
}
if (item < midValue)
right = mid;
else
left = mid + 1;
}
Insert(right, item);
return right;
}
void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
{ CPointerVector::Sort(compare, param); }
static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
{ return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }
};
#endif
MyVector.cpp
#include "StdAfx.h"
#include <string.h>
#include "MyVector.h"
CBaseRecordVector::~CBaseRecordVector() { ClearAndFree(); }
void CBaseRecordVector::ClearAndFree()
{
Clear();
delete []((unsigned char *)_items);
_capacity = 0;
_size = 0;
_items = 0;
}
void CBaseRecordVector::Clear() { DeleteFrom(0); }
void CBaseRecordVector::DeleteBack() { Delete(_size - 1); }
void CBaseRecordVector::DeleteFrom(int index) { Delete(index, _size - index); }
void CBaseRecordVector::ReserveOnePosition()
{
if (_size != _capacity)
return;
unsigned delta = 1;
if (_capacity >= 64)
delta = (unsigned)_capacity / 4;
else if (_capacity >= 8)
delta = 8;
Reserve(_capacity + (int)delta);
}
void CBaseRecordVector::Reserve(int newCapacity)
{
// if (newCapacity <= _capacity)
if (newCapacity == _capacity)
return;
if ((unsigned)newCapacity >= ((unsigned)1 << (sizeof(unsigned) * 8 - 1)))
throw 1052353;
size_t newSize = (size_t)(unsigned)newCapacity * _itemSize;
if (newSize / _itemSize != (size_t)(unsigned)newCapacity)
throw 1052354;
unsigned char *p = NULL;
if (newSize > 0)
{
p = new unsigned char[newSize];
if (p == 0)
throw 1052355;
int numRecordsToMove = (_size < newCapacity ? _size : newCapacity);
memcpy(p, _items, _itemSize * numRecordsToMove);
}
delete [](unsigned char *)_items;
_items = p;
_capacity = newCapacity;
}
void CBaseRecordVector::ReserveDown()
{
Reserve(_size);
}
void CBaseRecordVector::MoveItems(int destIndex, int srcIndex)
{
memmove(((unsigned char *)_items) + destIndex * _itemSize,
((unsigned char *)_items) + srcIndex * _itemSize,
_itemSize * (_size - srcIndex));
}
void CBaseRecordVector::InsertOneItem(int index)
{
ReserveOnePosition();
MoveItems(index + 1, index);
_size++;
}
void CBaseRecordVector::Delete(int index, int num)
{
TestIndexAndCorrectNum(index, num);
if (num > 0)
{
MoveItems(index, index + num);
_size -= num;
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.