Reputation: 3172
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;
}
Upvotes: 1
Views: 70
Reputation: 9691
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.
Upvotes: 1