// stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>
using namespace std;
#include "Animal.h"
// TODO: reference additional headers your program requires here
class Animal
{
private:
int itsWeight;
public:
Animal(int);
Animal();
~Animal() {}
int getWeight() const { return itsWeight; }
void Display() const;
};
template <class T>
class Array
{
private:
T *pType;
int itsSize;
const int defaultSize = 10;
public:
//constructors
Array(int itsSize = defaultSize);
Array(const Array &rhs);
~Array() { delete[] pType; }
//operators
Array& operator=(const Array&);
T& operator[](int offSet){ return pType[offSet]; }
const T& operator[](int offSet) const { return pType[offSet]; }
//methods of Access
int getSize() const { return itsSize; }
};
//constructor
template <class T>
Array<T>::Array(int size) :
itsSize(size)
{
pType = new T[size];
for (int i = 0; i < size; i++)
{
pType[i] = 0;
}
}
//copy-constructor
template <class T>
Array<T>::Array(const Array &rhs)
{
itsSize = rhs.getSize();
pType = new T[itsSize];
for (int i = 0; i < itsSize; i++)
{
pType[i] = rhs[i];
}
}
//operator prisvoeniya
template <class T>
Array<T>& Array<T>::operator=(const Array &rhs)
{
if (this == &rhs)
return *this;
delete[] pType;
itsSize = rhs.getSize();
pType = new T[itsSize];
for (int i = 0; i < itsSize; i++)
{
pType[i] = rhs[i];
}
return *this;
}
//this is the file "Animal.cpp"
#include "stdafx.h"
#include "Animal.h"
Animal::Animal()
{
itsWeight = 0;
}
Animal::Animal(int weight)
{
itsWeight = weight;
}
void Animal::Display() const
{
cout << itsWeight;
}
// the main function
#include "stdafx.h"
int_tmain(int argc, _TCHAR* argv[])
{
Array<int> theArray; //Integer array
Array<Animal> theZoo; //Animal array
Animal *pAnimal;
//filling the array
for (int i = 0; i < theArray.getSize(); i++)
{
theArray[i] = i * 2;
pAnimal = new Animal[i * 3];
theZoo[i] = *pAnimal;
delete pAnimal;
}
for (int j = 0; j < theArray.getSize(); j++)
{
cout << "theArray[" << j << "]:\t";
cout << theArray[j]<<"\t\t";
cout << "theZoo[" << j << "]:\t";
theZoo[j].Display();
cout << endl;
}
return 0;
}
The problem is that: The compiler gives me the errors
Error 1 error C2648: 'Array<int>::defaultSize' : use of member as default parameter requires static member
d:\documents\work\c++ files\tigrans\homework10\templates\templates\templates\animal.h 28 1 Templates
Error 2 error C2648: 'Array<Animal>::defaultSize' : use of member as default parameter requires static member
d:\documents\work\c++ files\tigrans\homework10\templates\templates\templates\animal.h 28 1 Templates
Anybody can help me to understand that. I change the
const int defaultSize=10;
to
static const int defaultSize=10
then there is not errors but in that time show Debug Assertion Failed!
This part of your code is dodgy
{
pAnimal = new Animal[i * 3];
theZoo[i] = *pAnimal;
delete pAnimal;
}
The first line allocates an array of i*3 Animals, using their default constructor (which makes an Animal with itsWeight=0). In the second line you assign the first these newly allocated Animals to theZoo[i]. Finally, the third line tries to de-allocate the Animals.
The last line contains an error, since you call delete on a pointer obtained with new [].
The whole concept of creating objects on the heap only to immediately destroy them is quite dubious -- perhaps you come from another programming language, where this is the only way to create things? First, you could simply use an automatic variable
{
Animal a; // or a(i*3);
theZoo[i] = a;
}
or yet briefer
{
theZoo[i] = Animal(i*3);
}
(Note the if you would use a std container, you could say theZoo.emplace_back(i*3);, avoiding the copy of Animal.)
Related
I've been having a hell of a time trying to solve this. What I am trying to do is use operator overloading so that my objects behave more like a multi dimensional array. I've found solutions to several of the smaller problems involved in making this happen but whenever I try to put it all together there is one issue or another, either lvalue assignment error or invalid initialization from rvalue or just straight up seg fault. I would appreciate any advice TY.
#include <iostream>
#include <vector>
#include <string>
class Matrix {
std::string **m;
public:
Matrix(int x, int y) {
m = new std::string*[x];
for (int i = 0; i < x; i++)
m[x] = new std::string[y];
}
class Proxy {
std::string *mm;
int lastIndex = 0;
public:
Proxy(std::string *s) : mm(s) {}
std::string &operator[](int index) {
lastIndex = index;
return mm[index];
}
std::string &operator=(std::string s) {
mm[lastIndex] = s;
return mm[lastIndex];
}
};
Proxy operator[](int index) {
return Proxy(m[index]);
}
};
int main()
{
Matrix *m = new Matrix(5, 5);
m[2][2] = std::string("It Works");
std::cout << m[2][2] << std::endl;
return 0;
In main(), m is a pointer to a Matrix object, so you need to dereference the pointer in order to access the Matrix object so you can invoke your Matrix::operator[] on it, eg:
int main()
{
Matrix *m = new Matrix(5, 5);
(*m)[2][2] = "It Works";
std::cout << (*m)[2][2] << std::endl;
delete m;
return 0;
}
Online Demo
Otherwise, the pointer is not really needed in your example to begin with, eg:
int main()
{
Matrix m(5, 5);
m[2][2] = "It Works";
std::cout << m[2][2] << std::endl;
return 0;
}
Online Demo
Either way, your Proxy does not need to implement operator= at all, eg:
class Proxy {
std::string *mm;
public:
Proxy(std::string *s) : mm(s) {}
std::string& operator[](int index) {
return mm[index];
}
};
A statement like m[2][2] = "..."; will not invoke your Proxy::operator=, it will invoke only Proxy::operator[]. A statement like m[2] = "..."; would be needed to invoke Proxy::operator=, which doesn't make sense to do in a multi-dimensional scenario.
Also, your Matrix constructor has a bug - writing to m[x] is going out of bounds of the m[] array, so the array is not actually filled at all, and you are corrupting surrounding memory, and leaking memory. You need to write to m[i] instead:
//m[x] = new std::string[y];
m[i] = new std::string[y];
After fixing that, Matrix is still leaking memory, as it does not implement a destructor to free the std::strings. You must delete[] anything you new[] (same with delete and new).
And then, you should finish off implementing support for the Rule of 3/5/0, by implementing a copy constructor and a copy assignment operator (your example code does not need them, but production code should always have them), eg:
#include <iostream>
#include <string>
#include <utility>
class Matrix {
std::string **m;
int m_x, m_y;
public:
Matrix(int x = 0, int y = 0) : m_x(x), m_y(y) {
m = new std::string*[x];
for (int i = 0; i < x; ++i)
m[i] = new std::string[y];
}
Matrix(const Matrix &src) : m_x(src.m_x), m_y(src.m_y) {
m = new std::string*[m_x];
for (int i = 0; i < m_x; ++i) {
m[i] = new std::string[m_y];
for (int j = 0; j < m_y; ++j) {
m[i][j] = src.m[i][j];
}
}
}
~Matrix() {
for (int i = 0; i < m_x; ++i)
delete[] m[i];
delete[] m;
}
Matrix& operator=(const Matrix &rhs) {
if (&rhs != this) {
Matrix temp(rhs);
std::swap(m, temp.m);
std::swap(m_x, temp.m_x);
std::swap(m_y, temp.m_y);
}
return *this;
}
class Proxy {
std::string *mm;
public:
Proxy(std::string *s) : mm(s) {}
std::string& operator[](int index) {
return mm[index];
}
};
Proxy operator[](int index) {
return Proxy(m[index]);
}
};
int main()
{
Matrix m(5, 5);
m[2][2] = "It Works";
std::cout << m[2][2] << std::endl;
Matrix m2(m);
std::cout << m2[2][2] << std::endl;
Matrix m3;
m3 = m2;
std::cout << m3[2][2] << std::endl;
return 0;
}
Online Demo
However, rather than using new[] manually, consider using std::vector instead (which you are already aware of, since you have #include <vector> in your code). This way, the Rule of 3/5/0 can be handled entirely by the compiler for you. std::vector and std::string are both fully compliant with the Rule, and so any compiler-generated destructor, copy constructor, and copy-assignment operator in Matrix will suffice, eg:
#include <iostream>
#include <vector>
#include <string>
class Matrix {
std::vector<std::vector<std::string>> m;
public:
Matrix(int x = 0, int y = 0) {
m.resize(x);
for (int i = 0; i < x; ++i)
m[i].resize(y);
}
class Proxy {
std::vector<std::string> &mm;
public:
Proxy(std::vector<std::string> &s) : mm(s) {}
std::string& operator[](int index) {
return mm[index];
}
};
Proxy operator[](int index) {
return Proxy(m[index]);
}
};
Online Demo
I have a assignment where I'm suppose to build template using these specifications.
ISet is a container that holds values of a certain where order doesn't matter and
which does not allow duplicates (or multiples).
A dynamically allocated array of type T should be used as an internal data structure for the Set.
The Set should inherit from the ISet interface below - this must not be modified:
template <typename T>
class ISet
{
public:
virtual bool insert (T element) = 0;
virtual bool remove (T element) = 0;
virtual int size () const = 0;
};
• insert (T element): adds elements to the set and returns true provided that
the element is not already present in the quantity (in which case the element is not added and false is returned).
• remove (T element): removes elements from the set and returns true.
If the element is missing in the quantity, false returns.
• size (): returns the number of elements in the set.
In addition to the member functions, you must implement constructor, destructor, copy constructor
and assignment operator.
And so far have I come up with this code:
#pragma once
#include <string>
#include <iostream>
using namespace std;
template <class T>
class ISet
{
public:
virtual bool insert(T element) = 0;
virtual bool remove(T element) = 0;
virtual int size() const = 0;
};
#pragma once
#include "ISet.h"
template <class T>
class Set : public ISet<T>
{
public:
Set(string name);
~Set();
Set(const Set &origin);
//Set& operator=(const Set &origin);
bool insert(T element);
bool remove(T element);
int size()const;
private:
string name;
T *arr;
int cap, nrOfElement;
};
template<class T>
Set<T>::Set(string name)
{
this->name = name;
this->cap = 10;
this->nrOfElement = 0;
this->arr = new T[this->cap];
}
template<class T>
Set<T>::~Set()
{
delete[] arr;
}
template<class T>
Set<T>::Set(const Set & origin)
{
this->nrOfElement = origin.nrOfElement;
this->cap = origin.cap;
arr = new T*[cap];
for (int i = 0; i < nrOfElement; i++)
{
arr[i] = origin.arr[i];
}
}
template<class T>
bool Set<T>::insert(T element)
{
bool found = false;
if (nrOfElement == 0)
{
this->arr[0] = element;
this->nrOfElement++;
}
else
{
for (int i = 0; i < this->nrOfElement; i++)
{
if (this->arr[i] == element)
{
i = this->nrOfElement;
found = true;
}
}
if (found == false)
{
this->arr[nrOfElement++] = element;
}
}
return found;
}
template<class T>
bool Set<T>::remove(T element)
{
bool removed = false;
for (int i = 0; i < this->nrOfElement; i++)
{
if (this->arr[i] == element)
{
this->arr[i] = this->arr[nrOfElement];
nrOfElement--;
removed = true;
}
}
return removed;
}
template<class T>
int Set<T>::size() const
{
return this->nrOfElement;
}
And my problems starts when I start to test this code by adding the different data-type we are suppose to test the template against.
#include "Set.h"
#include "ISet.h"
#include "Runner.h"
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
Set<string> test("test");
test.insert("lol");
cout << test.size();
test.remove("lol");
cout << test.size();
Set<Runner> test2("test");
getchar();
return 0;
}
Getting the error saying that "No operator found which takes a left-hand operand type of 'Runner'. So I have to create a operator== that handles this but don't know?
Runner class looks like this:
#pragma once
#include "Competitor.h"
#include <string>
using namespace std;
class Runner : public Competitor
{
public:
Runner();
Runner(string firstName, string lastName, int startNr);
~Runner();
void addResult(int resultTime);
int getResult() const;
string toString() const;
Runner *clone() const;
private:
int resultTime;
};
#include "Runner.h"
Runner::Runner()
{
this->resultTime = 0;
}
Runner::Runner(string firstName, string lastName, int startNr) : Competitor(firstName, lastName, startNr)
{
this->resultTime = 0;
}
Runner::~Runner()
{
}
void Runner::addResult(int resultTime)
{
this->resultTime = resultTime;
}
int Runner::getResult() const
{
return this->resultTime;
}
string Runner::toString() const
{
return (to_string(this->resultTime) + " sec");
}
Runner * Runner::clone() const
{
return new Runner(*this);
}
How do I build a operator== that will work for this?
You need to add operator== to the Runner class:
bool operator==(const Runner& other) const;
In the class constructor, I am initializing other objects and pushing these objects to my class vector member. From what I understand, the vector create a copy of the object and stores it so that it doesn't go out of scope. However, when verifying the objects in another class function, they are not initialized anymore. Here's a example code to explain the behaviour:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
class Square {
private:
int size_ = 0;
int colour_ = 0;
public:
Square(){
size_ = 0;
colour_ = 0;
}
void init(int size, int colour) {
size_ = size;
colour_ = colour;
}
int get_size() { return size_; }
};
class SetSquares {
private:
std::vector<Square> squares_;
int number_;
public:
SetSquares(): number_(0) {}
void init(int num) {
number_ = num;
squares_.clear();
squares_.resize(num);
for (int i=0; i < num; i++) {
Square square;
square.init(i, i);
squares_.push_back(square);
}
}
void sample(int i) {
if (i >= number_) { return; }
std::cout << "Square size is: " << squares_[i].get_size() << std::endl;
}
};
int main()
{
SetSquares set_of_squares;
set_of_squares.init(7);
set_of_squares.sample(4);
return 0;
}
resize(n) will create n default constructed elements in a vector and push_back will append new elements after those n elements. Use reserve and push_back or resize and index operator as suggested in comment.
Say I have a simple vector class, vec:
#include <iostream>
#include <stdlib.h>
class vec {
public:
vec() {}
// Constructor.
vec(int n) {
len = n;
data = new double[len];
}
// Destructor.
~vec() { delete [] data; }
// Accessor.
double & operator[](int i) const {
check_index(i);
return data[i];
}
// Other methods...
// ....
protected:
int len;
double * data;
void check_index(int i) const {
if(i < 0 || i >= len) {
std::cerr << "Bad access.\n";
exit(1);
}
}
};
Now suppose I have a special type of vector with sparse structure, e.g., where every even-index is zero. Call this oddvec. Instances of oddvec should be declared just as with the vec class, but underneath, the memory use should be efficient since only half the data is non-zero.
The accessor for the oddvec class should return 0 if the index is even, and return the odd-index element (stored sequentially) otherwise. There a couple problems with this:
The double & return type is violated if the index is even, since the constant value, 0, is returned.
It's not clear to me how to handle the situation when an even index element is used as an lvalue. E.g., v[0] = 3.0 should not be allowed in the oddvec class, but is perfectly acceptable in the vector class. We can't simply throw an error when even indexes are used, because even indexes are fine as long as the intention is as an rvalue.
How do I design the accessor function for the oddvec class, while both keeping the memory storage efficient and inheriting all the methods from the parent?
Non-working example of oddvec:
class oddvec : public vec {
public:
// Constructor.
oddvec(int n) {
len = n;
data = new double[len/2];
}
// Accessor (doesn't work!)
double & operator[](int i) const {
check_index(i);
if (i%2 == 0)
return 0;
else
return data[(i-1)/2];
}
};
Upon compilation:
main.cpp: In member function ‘double& oddvec::operator[](int) const’:
main.cpp:49:20: error: invalid initialization of non-const reference of type ‘double&’ from an rvalue of type ‘double’
return 0;
Working example using proxy classes:
I have implemented a proxy class as suggested in the answer below.
proxies.h
#ifndef PROXIES_H
#define PROXIES_H
#include <iostream>
#include <stdlib.h>
class proxy {
public:
proxy(int i, double v, double * d) {
index = i;
value = v;
data = d;
}
void operator=(double rhs) {
data[index] = rhs;
}
friend std::ostream & operator<<(std::ostream & outs, const proxy & p) {
outs << p.value;
return outs;
}
protected:
int index;
double value;
double * data;
};
class oddproxy : public proxy {
public:
oddproxy(int i, int v, double * d) : proxy(i, v, d) {}
void operator=(double rhs) {
if (index%2 == 0) {
std::cerr << "Even entries of oddvec are not assignable.\n";
exit(1);
}
data[index/2] = rhs;
}
};
#endif
vectors.h
#ifndef VECTORS_H
#define VECTORS_H
#include "proxies.h"
class vec {
public:
vec() {}
// Constructor.
vec(int n) {
len = n;
data = new double[len];
}
// Destructor.
~vec() { delete [] data; }
// Accessor.
proxy operator[](int i) const {
check_index(i);
return proxy(i, data[i], data);
}
inline int length() const { return len; }
// Other methods...
// ....
protected:
int len;
double * data;
void check_index(int i) const {
if(i < 0 || i >= len) {
std::cerr << "Bad access.\n";
exit(1);
}
}
};
class oddvec : public vec {
public:
// Constructor.
oddvec(int n) {
len = n;
data = new double[len/2];
}
// Accessor.
oddproxy operator[](int i) const {
check_index(i);
return oddproxy(i, (i%2 == 0) ? 0 : data[i/2], data);
}
};
#endif
main.cpp
#include <iostream>
#include "vectors.h"
int main () {
int N = 5;
vec V(N);
oddvec O(N);
for(int i=0; i < V.length(); i++) {
V[i] = i;
if(i%2 != 0) {
O[i] = i;
}
}
for(int i=0; i < O.length(); i++) {
std::cout << "V[" << i << "]=" << V[i] << ", "
<< "O[" << i << "]=" << O[i] << "\n";
}
O[0] = 13;
return 0;
}
output
V[0]=0, O[0]=0
V[1]=1, O[1]=1
V[2]=2, O[2]=0
V[3]=3, O[3]=3
V[4]=4, O[4]=0
Even entries of oddvec are not assignable.
You can use proxy object to do this.
simple sample code:
#include <iostream>
#include <vector>
using namespace std;
class very_odd_vector{
public:
class only_odd_proxy;
friend class only_odd_proxy;
only_odd_proxy operator [](int index);
int operator [](int index)const{return index%2==0?0:content[index/2];}
unsigned int size()const{return content.size()*2;}
private:
vector<int> content{1,3,5,7,9};
};
class very_odd_vector::only_odd_proxy{
public:
only_odd_proxy(very_odd_vector& vec,int index):vec(vec),index(index){}
operator int(){return index%2==0 ? 0 : vec.content[index/2];}
only_odd_proxy& operator =(int value){
if(index%2==0)
cout << "BAD OPERATION";//any error you want
else
vec.content[index/2] = value;
return *this;
}
private:
very_odd_vector& vec;
int index;
};
auto very_odd_vector::operator [](int index)->only_odd_proxy{return only_odd_proxy(*this,index);}
int main(){
very_odd_vector v;
cout << "reading value\n";
for(int i=0;i<v.size();++i)
cout << v[i] <<'\n';
cout << "writting value\n";
for(int i=0;i<v.size();++i){
cout << i << ':';
v[i]=10;
cout << '\n';
}
cout << "reading value\n";
for(int i=0;i<v.size();++i)
cout << v[i] <<'\n';
}
Edit for updated part of question :
I think this class will fit your need more.
//Both base and inherit class return this class
class maybe_readonly_proxy {
public:
maybe_readonly_proxy(double* data, bool readonly):readonly(readonly),data(data){}
maybe_readonly_proxy& operator=(double rhs) {
if(readonly){/*whatever error*/}
else {*data = rhs;}
return *this;
}
operator double()const{return *data;}
private:
bool readonly;
double * data;
};
You may need a variable to contain readonly (0 in this case) value, or modify the operator double() the check readonly state
Or just implement get and set method separately and do not use this proxy may be another choice.
I'm doing an assignment and I've put together a template class for a Vector, and now have inherited it (per the assignment) to make it a sort-able. At the very end of the void SearchableVector<T>::add(T itemToAdd) method it throws a Debug Assertion Failed! error. The full text of the error is as follows:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: ...tudio 2012\Projects\COSC 1437\Program 10\Debug\Program 10.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
I've looked around and I realize this is a pretty common error usually related to memory management. Often calling delete on inappropriate things. I must be doing something similar because I'm getting the error, but I cannot find what I'm doing wrong. If you could help me out and/or point me in the right direction that would be much appreciated.
Main.cpp
#include "SimpleVector.h"
#include "SearchableVector.h"
#include <stdlib.h>
#include <time.h>
void main()
{
srand (time(NULL));
SearchableVector<int> v(0);
for (int i = 0; i < 20; i++)
{
v.add(rand() % 20);
}
v.print();
}
SimpleVector.h
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <stdexcept>
#include <iomanip>
using namespace std;
template<class T>
class SimpleVector {
public:
//Constructors
SimpleVector(); //default constructor, size 0
SimpleVector(int); //parameterized constructor with default size
SimpleVector(const SimpleVector& a); //copy constructor
~SimpleVector(); //destructor
T& operator[](int) const;
SimpleVector<T>& operator=(SimpleVector<T>);
const bool operator==(SimpleVector&) const;
void push_back(T);
T& pop_back();
T& getElement(int);
int getSize() const;
void print() const;
protected:
int size;
T* internalArray;
void SimpleVector<T>::swap(SimpleVector&);
};
template<class T>
SimpleVector<T>::SimpleVector()
{
size = 0;
internalArray = nullptr;
}
template<class T>
SimpleVector<T>::SimpleVector(int sizeOfArray)
{
if (sizeOfArray < 0) throw "SimpleVector size must not be less than 0";
internalArray = new T[sizeOfArray]();
size = sizeOfArray;
}
template<class T>
SimpleVector<T>::SimpleVector(const SimpleVector& vectorToCopy):size(vectorToCopy.getSize()), internalArray( new T[vectorToCopy.getSize()] )
{
for (int i = 0; i < size; i++)
internalArray[i] = vectorToCopy.internalArray[i];
}
template<class T>
SimpleVector<T>::~SimpleVector() {
//cout << "Destructor called" << std::endl;
delete[] internalArray;
}
template<class T>
T& SimpleVector<T>::operator[](int i) const {
if (i<0 || i>=size) throw "Vector::operator[] : index is out of range";
return internalArray[i];
}
template<class T>
SimpleVector<T>& SimpleVector<T>::operator=(SimpleVector<T> rightSide) {
rightSide.swap(*this);
return *this;
}
template<class T>
const bool SimpleVector<T>::operator==(SimpleVector& right) const {
if (size() != right.size())
return false;
else {
for (int i = 0; i < size(); i++){
if (internalArray[i] != right[i])
return false;
}
}
return true;
}
template<class T>
void SimpleVector<T>::push_back(T itemToAdd) {
SimpleVector<T> temp(size + 1);
for (int i = 0; i < size; i++)
temp[i] = internalArray[i];
temp[size] = itemToAdd;
temp.swap(*this);
}
template<class T>
T& SimpleVector<T>::pop_back()
{
SimpleVector<T> temp(size - 1);
for (int i = 0; i < size; i++)
temp[i] = internalArray[i];
T pop = internalArray[size-a];
temp.swap(*this);
return pop;
}
template<class T>
T& SimpleVector<T>::getElement(int indexToGet)
{
return internalArray[indexToGet];
}
template<class T>
int SimpleVector<T>::getSize() const {
return this->size;
}
template<class T>
void SimpleVector<T>::print() const
{
for (int i = 0; i < size; i++)
{
std::cout << internalArray[i];
if (i!=(size-1))
std::cout << ",";
else
std::cout << std::endl;
if (i%10 == 0 && i!=0)
std::cout <<std::endl;
}
}
template<class T>
void SimpleVector<T>::swap(SimpleVector& other)
{
std::swap(internalArray, other.internalArray);
std::swap(size, other.size);
}
#endif
SearchableVector.h
#ifndef SEARCHABLEVECTOR_H
#define SEARCHABLEVECTOR_H
#include "SimpleVector.h"
template<class T>
class SearchableVector : protected SimpleVector<T>
{
public:
SearchableVector(int);
SearchableVector(const SearchableVector&);
~SearchableVector();
void add(T);
T getElement(int);
int getSize() const;
void print() const;
int search(T);
};
template<class T>
SearchableVector<T>::SearchableVector(int sizeOfArray) : SimpleVector(sizeOfArray)
{
}
template<class T>
SearchableVector<T>::SearchableVector(const SearchableVector& vectorToCopy) : SimpleVector(vectorToCopy)
{
}
template<class T>
SearchableVector<T>::~SearchableVector()
{
delete[] internalArray;
}
template<class T>
void SearchableVector<T>::add(T itemToAdd)
{
bool flag = false;
SearchableVector<T> temp(size + 1);
for (int i = 0; i < size; i++)
{
if ((itemToAdd <= internalArray[i]) && (flag == false))
{
temp[i] = itemToAdd;
i++;
flag = true;
}
temp[i] = internalArray[i];
}
if (flag == false)
temp[size] = itemToAdd;
temp.swap(*this);
} // !*******************! THROWS THE ERROR RIGHT HERE !*******************!
template<class T>
T SearchableVector<T>::getElement(int elementToGet)
{
return SimpleVector::getElement(elementToGet);
}
template<class T>
int SearchableVector<T>::getSize() const
{
return SimpleVector::getSize();
}
template<class T>
void SearchableVector<T>::print() const
{
SimpleVector::print();
}
template<class T>
int SearchableVector<T>::search(T itemToSearchFor)
{
}
#endif
First of all, when using inheritance, 99% of the time you should use a virtual destructor.
That's very important.
virtual ~SimpleVector();
When deleting an object, its base class destructor is called too.
And in your case you have delete[] internalArray; in both destructors.
Just leave that delete in the base class, because that member belongs to it, and it should take care of it.
Next time you encounter something like this, put a breakpoint near all the delete calls for that object type, then you can see which ones are called and in what order.