Please use vec.h as is and create a file vec.cpp with the methods that are not y
ID: 639658 • Letter: P
Question
Please use vec.h as is and create a file vec.cpp with the methods that
are not yet implemented in vec.h
The method push_back( ) is the one we discussed in class.
We will discuss methods that end with a "const", like size( ) and
operator [ ], next week. For now, please use them as they are.
You will need to add the operator <<( ) in vec.h
Use lab04.cpp as is because it uses the Vec methods as they should
be implemented.
Note that, if you choose NOT to work on the optional part of this
assignment, you need to comment the lines from
cout << " BEGINNING OF THE OPTIONAL PART... ";
up to, but not including,
return 0;
This assignment is due on the BlackBoard by midnight one week after it is posted.
Submit only the files FAUID_lab03.cpp FAUID_vec.cpp.
Please see lab04out.txt with the kind of output we expect from your program.
No late assignments.
Please
- use braces around any block
- use blocks as we did in our class examples
- indent your code as we have used indentations in our examples
- comment your code; do not over comment your code
Penalties:
o -2 for each missing block
o -2 for each missing indentation
o no credit if your cpp file does not compile or does not run
o some partial credit if your program crashes with different
input values depending on the problem
Extra credit:
- three extra points if your program correctly implements
void erase( int idx, int howmany );
that appears in vec.h and you use the optional part of lab-04.cpp
end of lab 04.
#include <iostream>
#include <iomanip>
using namespace std;
#include "vec.h"
int main( )
{
Vec v; // v is an object of type Vec
v.push_back( 10 ); // push 5 ints into v
v.push_back( 20 );
v.push_back( 30 );
v.push_back( 40 );
v.push_back( 50 );
v.push_back( 60 ); // try to push one element too many
cout << "after initializing v: " << v << ' ';
v.pop_back( ); // remove the last element of v
cout << "after popping last element of v: " << v << ' ';
v.erase( 0 ); // erase the first element of v
cout << "after erasing first element of v: " << v << ' ';
v.insert( 0, 60 ); // insert value 60 at index 0
cout << "after inserting 60 at index 0 of v: " << v << ' ';
v.erase( 1 ); // erase the second element of v
cout << "after erasing second element of v: " << v << ' ';
// erase the last element of v
v.erase( v.size( ) - 1 );
cout << "after erasing the last element of v: " << v << ' ';
v.erase( 0 ); // erase the first element of v
cout << "after erasing the 1st element of v: " << v << ' ';
v.insert( 0, 10 ); // insert 10 at position 0
v.insert( 1, 20 ); // insert 20 at position 1
v.insert( 3, 40 ); // insert 40 at position 3
cout << "after inserting three elements in v: " << v << ' ';
v.insert( 5, 50 ); // try to insert 50 at position 5; invalid!
cout << "after trying to insert 50 at an invalid loc in v: "
<< v << ' ';
// beginning of the optional part of lab-04
// if you choose NOT to work on the optional part, please comment
// the lines below up to, but not including, return 0;
cout << " BEGINNING OF THE OPTIONAL PART... ";
v.erase( 0, 2 ); // erase two elements beginning a loc. 0
cout << "after erasing two elements starting at 0: " << v << ' ';
v.erase( 3, 1 ); // erase one elements beginning a loc. 3
cout << "after attempting to erase one element starting at 3: "
<< v << ' '; // no changes; position is invalid
v.erase( 1, 1 ); // erase one elements beginning a loc. 1
cout << "after erasing one element starting at 1: "
<< v << ' ';
v.insert( 0, 10 ); // insert 10 at position 0
v.insert( 1, 20 ); // insert 20 at position 1
v.insert( 3, 40 ); // insert 40 at position 3
cout << "after inserting three elements in v: " << v << " ";
v.erase( 4, 2 ); // invalid erase; no location 4
cout << "no change in v after invalid erase location: "
<< v << " ";
v.erase( 3, 4 ); // invalid erase; no 4 elements starting at 3
cout << "no change in v after invalid erase range: "
<< v << " ";
v.erase( 0, 4 ); // erase all four elements in v
cout << "after erasing all elements in v: " << v << " ";
v.push_back( 10 ); // insert 10 at position 0
v.push_back( 20 ); // insert 20 at position 1
v.push_back( 30 ); // insert 30 at position 2
cout << "after inserting three elements in v: " << v << ' ';
return 0;
}
NB ---- THIS IS VEC.H
class Vec
{
public:
Vec( ); // constructor
void push_back( int ); // similar to vector
void pop_back( ); // remove last element in Vec
void erase( int idx ); // erase element at position idx
// optional: // erase howmany elements starting at idx
void erase( int idx, int howmany );
// insert a value at position idx
void insert( int idx, int value );
int size( ) const; // number of elements in array
// use operator [ ] as in a vector
int operator[ ]( int ) const;
private:
int array[ 5 ]; // local attribute
int loc; // local index
};
inline Vec::Vec( ) // constructor
{
cout << "in Vec::Vec( ) ";
loc = 0; // loc refers to the next empty location
}
// size of the object
inline int Vec::size( ) const
{
return loc;
}
// return a copy of element at index i
inline int Vec::operator [ ]( int i ) const
{
if( i >= 0 && i < loc )
{ // i is within the range of elements in array
return array[ i ];
}
else
{
return -1; // invalid index; return -1
}
}
OUTPUT
in Vec::Vec( )
push_back( 10 ) at location 0
push_back( 20 ) at location 1
push_back( 30 ) at location 2
push_back( 40 ) at location 3
push_back( 50 ) at location 4
after initializing v:
10 20 30 40 50
pop_back( ) at location 4
after popping last element of v:
10 20 30 40
erase( 0 )
after erasing first element of v:
20 30 40
insert( 0, 60 )
after inserting 60 at index 0 of v:
60 20 30 40
erase( 1 )
after erasing second element of v:
60 30 40
erase( 2 )
after erasing the last element of v:
60 30
erase( 0 )
after erasing the 1st element of v:
30
insert( 0, 10 )
insert( 1, 20 )
insert( 3, 40 )
after inserting three elements in v:
10 20 30 40
insert( 5, 50 )
after trying to insert 50 at an invalid loc in v:
10 20 30 40
BEGINNING OF THE OPTIONAL PART...
erase( 0, 2 )
after erasing two elements starting at 0:
30 40
erase( 3, 1 )
after attempting to erase one element starting at 3:
30 40
erase( 1, 1 )
after erasing one element starting at 1:
30
insert( 0, 10 )
insert( 1, 20 )
insert( 3, 40 )
after inserting three elements in v:
10 20 30 40
erase( 4, 2 )
no change in v after invalid erase location:
10 20 30 40
erase( 3, 4 )
no change in v after invalid erase range:
10 20 30 40
erase( 0, 4 )
after erasing all elements in v:
push_back( 10 ) at location 0
push_back( 20 ) at location 1
push_back( 30 ) at location 2
after inserting three elements in v:
10 20 30
Explanation / Answer
main.cpp
#include <iostream>
#include "Vec.h"
using std::cout;
using std::endl;
int main()
{
Vec<int> v;
for (int i = 1; i < 10; ++i)
v.push_back(i);
for(Vec<int>::const_iterator iter = v.begin();
iter != v.end(); ++iter)
cout << *iter << endl;
return 0;
}
Vec.h
#ifndef GUARD_Vec_h
#define GUARD_Vec_h
#include <cstddef>
#include <memory>
template <class T> class Vec {
public:
// member variables
typedef T* iterator;
typedef const T* const_iterator;
typedef std::size_t size_type;
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
// constructors + destructors
Vec() { create(); }
explicit Vec(size_type n, const T& t = T()) { create(n, t); }
Vec(const Vec& v) { create(v.begin(), v.end()); }
~Vec() { uncreate(); }
// methods
T& operator[](size_type i) { return data[i]; }
const T& operator[](size_type i) const { return data[i]; }
void push_back(const T& t) {
if (avail == limit)
grow();
unchecked_append(t);
}
size_type size() const { return avail - data; }
iterator begin() { return data; }
const_iterator begin() const { return data; }
iterator end() { return avail; }
const_iterator end() const { return avail; }
private:
iterator data;
iterator avail;
iterator limit;
std::allocator<T> alloc;
void create();
void create(size_type, const T&);
void create(const_iterator, const_iterator);
void uncreate();
void grow();
void unchecked_append(const T&);
};
#endif GUARD_Vec_h
Vec.cpp
#include <algorithm>
#include <cstddef>
#include <memory>
#include "Vec.h"
using std::allocator;
using std::max;
using std::uninitialized_copy;
using std::uninitialized_fill;
using std::ptrdiff_t;
template <class T> void Vec<T>::create()
{
data = avail = limit = 0;
}
template <class T> void Vec<T>::create(size_type n, const T& val)
{
data = alloc.allocate(n);
limit = avail = data + n;
uninitialized_fill(data, limit, val);
}
template <class T> void Vec<T>::create(const_iterator i, const_iterator j)
{
data = alloc.allocate(j - i);
limit = avail = uninitialized_copy(i, j, data);
}
template <class T> void Vec<T>::uncreate()
{
if (data) {
iterator it = avail;
while (it != data)
alloc.destroy(--it);
alloc.deallocate(data, limit - data);
}
data = limit = avail = 0;
}
template <class T> void Vec<T>::grow()
{
size_type new_size = max(2 * (limit - data), ptrdiff_t(1));
iterator new_data = alloc.allocate(new_size);
iterator new_avail = uninitialized_copy(data, avail, new_data);
uncreate();
data = new_data;
avail = new_avail;
limit = data + new_size;
}
template <class T> void Vec<T>::unchecked_append(const T& val)
{
alloc.construct(avail++, val);
}