Error with the Copy constructor and equality operator - c++

I am making my own implementation of the class "vector" with templates as practise. Everything seems to be working except the Copy constructor and the overloaded = operator. I am not sure where exactly the problem is. I will post the entire source code below:(Also I am not sure if I have any leaks)
#include <iostream>
#include <string>
using namespace std;
template <typename TT1>
class Vector{
private:
int size;
TT1* ptr;
public:
Vector();
~Vector();
Vector(int size);
Vector(const Vector& a);
Vector<TT1>& operator=(const Vector& a);
void set(int position, TT1 data);
TT1 get(int position);
int get_size();
};
//------Default Constructor------
template <typename TT1>
Vector<TT1> :: Vector()
{
size = 0;
ptr = NULL;
}
//-------Copy Constructor-------
template <typename TT1>
Vector<TT1> :: Vector(const Vector<TT1>& a)
{
if(a.ptr != NULL)
{
this->size = a.size;
delete[] ptr;
ptr = new TT1[size];
for ( int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
}
}
//------Destructor-------
template <typename TT1>
Vector<TT1> :: ~Vector()
{
delete[] ptr;
}
//-----Overloaded = operator----
template <typename TT1>
Vector<TT1>& Vector<TT1> :: operator=(const Vector<TT1>& a)
{
if(this != &a)
{
this->size = a.size;
delete[] this->ptr;
this->ptr = new TT1[a.size];
for (unsigned int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
return *this;
}
}
//----Constructor with size---
template<typename TT1>
Vector<TT1> :: Vector(int size)
{
this->size = size;
ptr = new TT1[size];
}
//---- Set data # Poisition----
template<typename TT1>
void Vector<TT1> :: set(int position, TT1 data)
{
*(ptr+ position) = data;
}
//----Get data From position----
template<typename TT1>
TT1 Vector<TT1> :: get(int position)
{
return *(ptr + position);
}
//-----Get size----
template<typename TT1>
int Vector<TT1> :: get_size()
{
return size;
}
void foo(Vector<string> a)
{
}
int main()
{
Vector<string> a(3);
a.set(0, "asd");
a.set(2, "hjk");
a.set(1, "34645!");
for(int i = 0; i < a.get_size(); i++)
{
cout << a.get(i) << endl;
}
Vector<string> b = a;
for(int i = 0; i < a.get_size(); i++)
{
cout << b.get(i) << endl;
}
foo(a);
return 0;
}
And now the parts where the mistakes are:
template <typename TT1>
Vector<TT1> :: Vector(const Vector<TT1>& a)
{
if(a.ptr != NULL)
{
this->size = a.size;
delete[] ptr;
ptr = new TT1[size];
for ( int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
}
}
And finally here:
//-----Overloaded = operator----
template <typename TT1>
Vector<TT1>& Vector<TT1> :: operator=(const Vector<TT1>& a)
{
if(this != &a)
{
this->size = a.size;
delete[] this->ptr;
this->ptr = new TT1[a.size];
for (unsigned int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
return *this;
}

You delete a pointer that was never allocated:
//-------Copy Constructor-------
template <typename TT1>
Vector<TT1> :: Vector(const Vector<TT1>& a)
{
std::cout << "Vector(const Vector<TT1>& a), " << a.size << std::endl;
if(a.ptr != NULL)
{
this->size = a.size;
delete[] ptr; //<-------------- no corresponding new
ptr = new TT1[size];
for ( int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
}
}
Just comment that out, and it works fine.
Edit: Per Mike Seymour's observation, the members esp. ptr should be initialized:
Vector<TT1> :: Vector(const Vector<TT1>& a) : size(0), ptr(NULL)
{
...
}
In addition, although the compiler accepts it for constructor/operator= apparently, you will otherwise get an 'incomplete type' error if you write code of the form
Vector(const Vector& a);
Vector<TT1>& operator=(const Vector& a);
Rather, for consistency and good style imho include the template parameters:
Vector(const Vector<TT1>& a);
Vector<TT1>& operator=(const Vector<TT1>& a);
And similarly in the definitions.

Related

Getting error in merging two arrays in c++?

I am trying to merge two dynamic arrays but I am getting an error in my merge function that
"data': is not a member of 'List<T>"
I know that the error is ocuring because the given parameter in the merge(const List& other) is list but I am confused how to access my ArrayList2 which has been passed in merge function in the main
my code is:
#include <iostream>
using namespace std;
template<class T>
class List {
public:
// return the capacity of the list
virtual size_t capacity() const = 0;
// return the number of elements in the list
virtual size_t size() const = 0;
// inserts an element to the beginning
virtual void push_front(const T& value) = 0;
// adds an element to the end
virtual void push_back(const T& value) = 0;
// removes the last element
virtual void pop_back() = 0;
// removes the first element
virtual void pop_front() = 0;
// remove the first occurrence of an element with the given value
virtual void remove(const T& val) = 0;
// merges two sorted lists
virtual void merge(const List<T>& other) = 0;
virtual ~List() {}
};
template<class T>
class ArrayList : public List<T>
{
private:
T* data;
size_t max_capacity;
size_t num_of_element;
public:
ArrayList() = delete; // disable default constructor
// constructor
ArrayList(size_t capacity) : max_capacity(capacity), num_of_element(0) {
data = new T[capacity];
}
// copy constructor
ArrayList(const ArrayList<T>& other_list) : max_capacity(other_list.max_capacity),
num_of_element(other_list.num_of_element) {
data = new T[max_capacity];
for (size_t i = 0; i < other_list.num_of_element; i++) {
data[i] = other_list.data[i];
}
}
// destructor
virtual ~ArrayList() {
delete[]data;
}
size_t capacity() const override {
return max_capacity;
}
size_t size() const override {
return num_of_element;
}
T& operator[](int index) {
return data[index];
}
bool operator==(const ArrayList<T>& other_list) {
// not comparing capacity as eventually array list can be made capacity irrelevant using dynamic allocation
if (num_of_element != other_list.num_of_element) {
return false;
}
for (int i = 0; i < num_of_element; i++) {
if (data[i] != other_list.data[i]) {
return false;
}
}
return true;
}
void push_front(const T& value)
{
}
void push_back(const T& value)
{
if (max_capacity > num_of_element)
{
num_of_element++;
data[num_of_element - 1] = value;
}
}
void pop_back()
{
}
void pop_front()
{
}
void remove(const T& val)
{
int i = 0, j;
while (i < max_capacity)
{
if (data[i] == val)
{
for (int j = i; j < num_of_element-1; j++)
data[j] = data[j + 1];
if (data[i] == val && (i + 1) > num_of_element - 1)
{
data[i] = {};
num_of_element--;
break;
}
num_of_element--;
}
else
i++;
}
}
void merge(const List<T>& other)
{
int i;
int newsize = size() + other.size();
T* temp = new T[newsize];
for (i = 0; i < num_of_element; i++)
temp[i] = data[i];
for (int j = 0; j < other.size(); j++)
{
temp[i] = other.data[j]; //I am getting error on this line
i++;
}
}
private:
void shift_left_to(size_t start) {
for (size_t i = start; i < num_of_element - 1; i++) {
data[i] = data[i + 1];
}
}
};
int main() {
ArrayList<int> list1(3);
list1.push_back(3);
list1.push_back(1);
list1.push_back(1);
ArrayList<int> list2(2);
list2.push_back(1);
list2.push_back(8);
list1.merge(list2);
/* for (size_t i = 0; i < list1.size(); i++)
cout<<list1[i]<<" ";
cout<<"Size:"<<list1.size()<<" Capacity:"<<list1.capacity();*/
system("pause");
return 0;
}
Presumably, all of your concrete List<T> classes (e.g. ArrayList<T>) will have some kind of accessors to the elements. You can make those accessors part of the List<T> interface and call them in the implementation of void merge(List<T> const&). As an example:
template <class T>
class List {
public:
// ...
virtual T& operator[](int index) = 0;
virtual T const& operator[](int index) const = 0;
};
template <class T>
class ArrayList : public List<T> {
private:
T* data;
size_t max_capacity;
size_t num_of_element;
public:
// ...
T& operator[](int index) override { return data[index]; }
T const& operator[](int index) const override { return data[index]; }
// ...
void merge(const List<T>& other) {
int i;
int newsize = size() + other.size();
T* temp = new T[newsize];
for (i = 0; i < num_of_element; i++) temp[i] = data[i];
for (int j = 0; j < other.size(); j++) {
temp[i] = other[j]; // < Use your List<T>::operator[] here
i++;
}
}
// ...
};
I'd say the message is quite descriptive: List does not have a member called data. You should use the [] operator instead to access the list elements in the merge function. [] operator is implemented by descendants of List.
temp[i] = other[j]

How to implemet copy constructor in C++

this is the header of a class that I have been designing for an assignment. I have included constructors, a destructors, as well as overloaded operators. Could you give me a hint how to properly define the constructors in a class using c++ 20 most recent features in an efficient way.
#ifndef VECTOR_DOUBLE_H
#define VECTOR_DOUBLE_H
#include <memory>
#include <vector>
class vector_double {
public:
vector_double(int size);
vector_double(std::initializer_list<double> lst);
vector_double(const double* array, int size);
vector_double(const vector_doubler& other);
vector_doubleoperator=(const vector_double& other);
// because I use a managed pointer I don't need a destructor
~vector_double() noexcept = default;
void set(int index, double val);
double& get(int index);
const double& get(int index) const;
int size() const;
void reset(double val);
void fill_from(std::initializer_list<double> lst);
void fill_from(const double* array, int size);
int copy_to(std::vector<double>& vec) const;
double& operator[](int index);
const double& operator[](int index) const;
operator double() const;
vector_double add(const vector_double& other) const;
vector_doubleadd(double number) const;
vector_doublemul_by(double number) const;
void resize(int size);
friend std::ostream& operator<<(std::ostream& out, const vector_double& vec);
private:
std::unique_ptr<double[]> m_array;
int m_size;
};
inline std::ostream& operator<<(std::ostream& out, const vector_double& vec){
if (vec.m_size == 0){
out << "{ }";
}
else{
auto first = true;
out << '{';
for (int i=0; i < vec.m_size; ++i){
if (!first)
out << ", ";
else
first = !first;
out << vec.m_array[i];
}
out << '}';
}
return out;
}
#endif //VECTOR_DOUBLE_H
This example definition may help, I tried sticking to C++20 features:
#include <cmath>
#include "vector_double.h"
vector_double::vector_double(int size):
m_array{ new double[size] },
m_size{size}
{}
vector_double::vector_double(std::initializer_list<double> lst): //Constructor that takes an init list
vector_double(lst.size())
{
std::copy(lst.begin(), lst.end(), m_array.get());
}
vector_double::vector_double(const double* array, int size): //Constructor that takes array and size
vector_double(size)
{
// std::copy(array, array + size, m_array.get());
std::copy(&array[0], &array[size], m_array.get());
}
vector_double::vector_double(const vector_double& other): //Copy Constructor
vector_double(other.m_size)
{
std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
}
vector_double& vector_double::operator=(const vector_double& other) {
if (this != &other) {
if (m_size != other.m_size) {
auto* array = new double[other.m_size];
m_array.reset(array);
m_size = other.m_size;
}
std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
}
return *this;
}
void vector_double::set(int index, double val) {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
m_array[index] = val;
}
double& vector_double::get(int index) {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
return m_array[index];
}
const double& vector_double::get(int index) const {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
return m_array[index];
}
int vector_double::size() const {
return m_size;
}
void vector_double::reset(double val) {
for (int i=0; i<m_size; ++i){
m_array[i] = val;
}
}
void vector_double::fill_from(std::initializer_list<double> lst) {
int size = std::min((int)lst.size(), m_size);
std::copy(lst.begin(), lst.begin() + size, &m_array[0]);
}
void vector_double::fill_from(const double* array, int size) {
size = std::min(size, m_size);
for (int i = 0; i < size; ++i) {
m_array[i] = array[i];
}
}
int vector_double::copy_to(std::vector<double>& vec) const {
for (int i = 0; i < m_size; ++i) {
vec.push_back(m_array[i]);
}
return m_size;
}
double& vector_double::operator[](int index) {
return m_array[index];
}
const double& vector_double::operator[](int index) const { //Overloading "[]" operator
return m_array[index];
}
vector_double::operator double() const {
double sum = 0.0;
for (int i = 0; i < m_size; ++i) {
sum += m_array[i] * m_array[i];
}
return std::sqrt(sum);
}
vector_double vector_double::add(const vector_double& other) const {
if (m_size != other.m_size)
throw std::logic_error("size mismatch");
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] += other[i];
}
return copy;
}
vector_double vector_double::add(double number) const {
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] += number;
}
return copy;
}
vector_double vector_double::mul_by(double number) const {
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] *= number;
}
return copy;
}
void vector_double::resize(int size) {
if (size != m_size){
auto array = new double[size] {0,};
auto common = std::min(size,m_size);
for (int i = 0; i < common; ++i) {
array[i] = m_array[i];
}
m_array.reset(array);
m_size = size;
}
}

Problem freeing memory (subject Template)

Set.h
#ifndef Set_h
#define Set_h
#include <iostream>
using namespace::std;
template <class T>
class Set {
T* group;
int size_group;
public:
Set():group(NULL),size_group(0){};
Set(T*,int);
Set(const Set<T>&);
~Set();
bool isThere(const T&)const;
void getType()const;
Set<T>& operator =(const Set<T>&);
bool operator ==(const Set<T>&) const;
void operator +=(const T);
void operator -=(const T&);
Set<T>& operator +(Set<T>&);
Set<T>& operator -(const Set<T>&);
bool operator >(const Set<T>&)const;
friend ostream& operator <<(ostream&,const Set<T>&);
};
//Realizations
template <class T>
Set<T>::Set(T* gro,int size):group(gro),size_group(size){}
template <class T>
Set<T>::Set(const Set<T>& obj){ // c'Ctor (copy)
this->size_group = obj.size_group;
this->group = new T[this->size_group];
for (int i = 0; i < size_group; i++) {
group[i] = obj.group[i];
}
}
template <class T>
void Set<T>::getType() const{
cout << "The type is: " << typeid(group).name() << endl;
}
template <class T>
Set<T>& Set<T>::operator = (const Set<T>& obj){
this->size_group = obj.size_group;
this->group = new T[size_group];
for (int i = 0; i < size_group; i++) {
this->group[i] = obj.group[i];
}
return *this;
}
template <class T>
bool Set<T>::operator==(const Set<T>& obj) const{
int count = 0;
T temp;
if(this->size_group != obj.size_group)
return false;
for (int i = 0; this->size_group; i++) {
temp = this->group[i];
count = 0;
for (int j = 0; j < obj.size_group; j++) {
if(temp == obj.group[j])
count++;
}
if(count != 1)
return false;
}
return true;
}
template <class T>
void Set<T>::operator+=(const T var){
if(!isThere(var)){
T* Temp = new T[this->size_group+1];
for (int i = 0; i < this->size_group; i++)
Temp[i] = this->group[i];
Temp[size_group] = var;
delete [] this->group;
this->size_group++;
this->group = Temp;
}
}
template <class T>
Set<T>& Set<T>::operator+(Set<T>& obj){ //
if(obj.size_group > this->size_group){
for (int i = 0; i < obj.size_group; i++){
for (int j = 0 ; j < this->size_group; j++){
if(!this->isThere(obj.group[i]))
*this += obj.group[i];
}
}
return *this;
}else{
for (int i = 0; i < this->size_group; i++){
for (int j = 0 ; j < obj.size_group; j++){
if(!obj.isThere(this->group[i]))
obj += this->group[i];
}
}
return obj;
}
}
template <class T>
bool Set<T>::isThere(const T& var) const{
for (int i = 0; i < this->size_group; i++) {
if(this->group[i] == var)
return true;
}
return false;
}
template <class T>
Set<T>::~Set() {
delete [] group;
}
#endif /* Set_h */
Main:
#include "Set.h"
int main() {
int arr[] = {3,7,8,1};
int arr2[] = {1,2,5};
Set<int> j(arr,4),l(arr2,3),k;
k = j + l;
}
I'm trying to merge two arrays, but my problem is with the method void Set<T>::operator+=(const T var) and this line delete [] this-> group;
I get this error:
Template & Exception (8421,0x1000dadc0) malloc: *** error for object 0x7ffeefbff400: pointer being Friday was not allocated
Template & Exception (8421,0x1000dadc0) malloc: *** set a breakpoint in malloc_error_break to debug
Your Set(T*,int) constructor is not allocating new[]'ed memory for group to point at, which means operator+= (and ~Set(), and operator=) will fail at runtime when they try to delete[] the memory that group points at, which in your example is local stack memory that main() owns and passes in to the j and l objects.
Your Set(T*,int) constructor must new[] the group array and copy the contents of the input gro array into it, similar to how your copy constructor does, eg:
template <class T>
Set<T>::Set(T* gro, int size) : group(NULL), size_group(0)
{
size_group = size;
group = new T[size];
for (int i = 0; i < size; i++) {
group[i] = gro[i];
}
}
On a side note, your operator= is leaking memory, as it does not delete[] the current group array before assigning a new group array. It should be making a temporary array, similar to how your operator+= does, eg:
template <class T>
Set<T>& Set<T>::operator=(const Set<T>& obj)
{
if (this != &obj){
T* Temp = new T[obj.size_group];
for (int i = 0; i < obj.size_group; i++)
Temp[i] = obj.group[i];
delete [] group;
group = Temp;
size_group = obj.size_group;
}
return *this;
}
Or better, use your copy constructor via the copy-swap idiom instead:
template <class T>
Set<T>& Set<T>::operator=(const Set<T>& obj)
{
if (this != &obj){
Set<T> temp(obj);
std::swap(group, temp.group);
std::swap(size_group, temp.size_group);
}
return *this;
}
Also, your operator+ is implemented all wrong. It needs to return a new Set that is the concatenation of the arrays of *this and obj, not modify obj or *this at all. As such, it needs to look more like this instead:
template <class T>
Set<T> Set<T>::operator+(const Set<T>& obj) const
{
Set<T> res(*this);
for (int i = 0; i < obj.size_group; i++) {
res += obj.group[i];
}
return res;
}

Cannot resize stack of type template

Im trying to resize my stack but my program keeps terminating after the 'cout'.
On the output terminal it displays 1 and then the program terminates. In this case T is an int and size is set to 10 by default. Any help will be much appreciated.
#include <iostream>
#include <fstream>
using namespace std;
template <typename T>
class stack {
public:
int topStack;
T* stack1;
int size;
void copy(const stack& other);
void move(stack&& other);
// constructor
stack ();
// destructor
~stack()
{
delete[] stack1;
};
// copy constructor
stack (const stack&);
// copy assignment
stack& operator= (const stack&);
// move constructor
stack (stack&&);
// move assignment
stack& operator= (stack&&);
T& top() const; // return the top element
void pop (); // remove the top element
void push(const T&); // add element on top of stack
void push (T&&); // add element on top of stack
bool empty() const; // is the stack empty?
void clear(); // remove all elements
ostream& print(ostream&, stack&);
void resize();
};
//Default Constructor
template <typename T>
stack<T>::stack()
{
size=10;
stack1= new T[size];
for(int b =0; b < size; b ++)
{
stack1[b] = T();
}
topStack =-1;
}
//Copy Constructor
template <typename T>
void stack<T>::copy(const stack& other)
{
topStack = other.topStack;
stack1= new T[other.size];
size =other.size;
for(int i=0; i< other.size ; i++)
{
stack1[i]=other.stack1[i];
}
}
//Copy assignment
template <typename T>
stack<T>& stack<T>::operator =(const stack& other)
{
if (this == &other) return *this;
T* store = new T[other.size];
for(int g =0; g < other.size ; g++)
{
store[g]= other.stack1[g];
}
delete[] stack1;
this->stack1 = store;
this->size = other.size;
this-> topStack = other.topStack;
return *this;
}
//Move Constructor
template<typename T>
void stack<T>::move(stack && other)
{
topStack = other.topStack;
other.topStack = 0;
stack1 = other.stack1;
for(int u =0; u < other.size ; u++)
{
other.stack1[u]=0;
}
size = other.size;
other.size=0;
}
//Move assignment
template <typename T>
stack<T>& stack<T>::operator= (stack&& other)
{
this->size = other.size;
other.size=0;
this->topStack = other.topStack;
other.topStack=0;
this->stack1 = other.stack1;
for(int u =0; u < this->size ; u++)
{
other.stack1[u]=0;
}
return *this;
}
//Checks if stack is empty
template <typename T>
bool stack<T>::empty() const
{
return topStack == -1;
}
//Resize array
template<typename T>
void stack<T>::resize()
{
cout << "DAYYYY55UM";
T* storage = new T[this->size*2];
cout << "DAYYYYUM";
for(int r=0; r < this->size ; r++)
{
storage[r]= this->stack1[r];
}
delete[] this->stack1;
this->stack1= storage;
this->size = size*2;
cout << "DAYYYYUM";
}
//Returns top
template <typename T>
T& stack<T>::top() const
{
if(empty())
{
cout << "ERROR: Stack is empty. "<< endl;
return;
//Make a throw catch statement here
}
return stack1[topStack];
}
//Pop
template <typename T>
void stack<T>::pop()
{
if(empty())
{
cout << "ERROR: Stack is empty." << endl;
return;
}
stack1[topStack] =0;
topStack--;
}
//Push
template <typename T>
void stack<T>::push(const T& q)
{
if(topStack < size)
{
topStack++;
stack1[topStack] = q;
}else{
resize();
}
}
//Push
template <typename T>
void stack<T>::push(T&& q)
{
if(topStack < size)
{
topStack++;
stack1[topStack] = q;
}else{
resize();
}
}
//Print Function
template <typename T>
ostream& stack<T>::print(ostream& os, stack& other)
{
os << other.stack1 ;
}
template <typename T>
void stack<T>::clear()
{
for(int g=0; g < size; g++ )
{
stack1[g]=0;
}
}
int main()
{
stack<int> world;
world.push(9);
world.push(40);
world.push(40);
world.push(9);
world.push(40);
world.push(40);
world.push(9);
world.push(40);
world.push(40);
world.push(9);
world.push(40);
world.push(40);
cout << world.stack1[12] << endl;
return 0;
}
That error means that you have an out of bounds array access somewhere that is corrupting malloc's data structures.
The error is in your push function:
template <typename T>
void stack<T>::push(T&& q)
{
if(topStack < size)
{
topStack++;
stack1[topStack] = q;
}else{
resize();
}
}
When you write the last item before resize, topStack is one less than size, which is a valid index (the last one, indeed), but then you increment it to size, and write the item in that position, and that's not a valid index.
By the way, you have a lot of errors with the indexes al over your class. My advice woulbe to take into account that c++ arrays start at 0 and end at size-1, and revise your code.
And have you noticed that when you resize the array you don't add the new item?

c++ using vector of employee pointers

I have created my vector class template and I have already done my employee classes of hourly and I salaried. I want to use the vector of employee pointers instead of the array of employee pointers, I'm trying to do that but when I run it just breaks while I have no error listed.
Also, I have used the at function like( payroll.at(i)->writeFile(out); ) to get access to an element, but I don't know what's wrong.
Any suggestion?
Thanks
here is my code:
myvector class template:
#include <iostream>
#include <string>
#include <cassert>
#include <algorithm>
const int CAPACITY = 4;
template <class T>
class MyVector {
public:
MyVector();
MyVector( int size);
MyVector( int size, const T & initial);
MyVector(const MyVector<T> & v);
~MyVector();
int capacity() const;
int size() const;
void push_back(const T & value);
//T & operator[](unsigned int index);
MyVector<T> & operator=(const MyVector<T> &);
void clear();
T at(int i);
friend ostream& operator<<(ostream &out, const MyVector<T>& );
private:
int applied;
int my_size;
int my_capacity;
T * buffer;
T * daArray;
};
template<class T>
MyVector<T>::MyVector()
{
my_capacity = 0;
my_size = 0;
buffer = 0;
applied = 0;
}
template<class T>
MyVector<T>::MyVector(const MyVector<T> & v)
{
my_size = v.my_size;
my_capacity = v.my_capacity;
buffer = new T[my_size];
for ( int i = 0; i < my_size; i++)
buffer[i] = v.buffer[i];
}
template<class T>
MyVector<T>::MyVector(int size)
{
my_capacity = size;
my_size = size;
buffer = new T[size];
}
template<class T>
MyVector<T>::MyVector( int size, const T & initial)
{
my_size = size;
my_capacity = size;
buffer = new T [size];
for (unsigned int i = 0; i < size; i++)
buffer[i] = initial;
//T();
}
template<class T>
MyVector<T> & MyVector<T>::operator = (const MyVector<T> & v)
{
delete[ ] buffer;
my_size = v.my_size;
my_capacity = v.my_capacity;
buffer = new T [my_size];
for (int i = 0; i < my_size; i++)
buffer[i] = v.buffer[i];
return *this;
}
template<class T>
void MyVector<T>::push_back(const T & i)
{
if (my_capacity == 0)
{
my_capacity = 1;
my_size = 1;
applied= 0;
buffer = new T[1];
buffer[0] = i;
}
else
{
if (applied+1 == my_capacity)
{
int newCapacity = my_capacity * CAPACITY;
daArray = new T[newCapacity];
for (int i = 0; i < my_size; i++)
{
daArray[i] = buffer[i];
}
my_capacity = newCapacity;
delete buffer;
my_size++;
applied++;
buffer[applied] = i;
}
else
{
if (my_size == applied + 1)
my_size++;
applied++;
buffer[applied] = i;
}
}
}
template<class T>
int MyVector<T>::size()const//
{
return my_size;
}
template<class T>
int MyVector<T>::capacity()const
{
return my_capacity;
}
template<class T>
MyVector<T>::~MyVector()
{
delete[ ] buffer;
}
template <class T>
void MyVector<T>::clear()
{
my_capacity = 0;
my_size = 0;
buffer = 0;
}
template <class T>
T MyVector<T>::at(int i)
{
if (i < 0 || i > my_size -1)
{
string error = "Index is undefined";
throw error;
}
return buffer[i];
}
template <class T>
ostream& operator<<(ostream &out, const MyVector<T>& v)
{
for (unsigned i = 0; i < v.size(); i++)
{
out << v[i] << " ";
}
return out;
}
main
int main() {
MyVector< employee*> payroll;
payroll.push_back(new Hourly ("H. Potter", "Privet Drive", "201-9090", 40, 12.00));
payroll.push_back(new Salaried ( "A. Dumbledore", "Hogewarts", "803-1230", 1200));
ofstream out;
out.open(file);
if (out.fail()) {
cout<<" could not open the file"<<endl;
system("PAUSE");
}
for (int i = 0; i < SIZE; i++) {
payroll.at(i)->writeFile(out);
}
out.close( );
}
You have a bug in your push_back method. You need something like this
if (applied+1 == my_capacity)
{
int newCapacity = my_capacity * CAPACITY;
daArray = new T[newCapacity];
for (int i = 0; i < my_size; i++)
{
daArray[i] = buffer[i];
}
my_capacity = newCapacity;
delete buffer;
buffer = daArray; // new line here
my_size++;
applied++;
buffer[applied] = i;
}
See where I've put the comment // new line here