Abstract Class Output problems - c++

This main program should ask the user to put in some numbers and store them into a dynamic array. The array should then be outputted its contents in a straight line, no end line commands, with a comma in between. I can't figure out how to start the program.
If you guys can help me find a way to do this, I would be eternally thankful!
Here is ListType.h:
#ifndef LISTTYPE_H_INCLUDED
#define LISTTYPE_H_INCLUDED
#include <iostream>
class ListType {
public:
ListType(size_t=10);
virtual ~ListType();
virtual bool insert(int)=0;
virtual bool erase();
virtual bool erase(int)=0;
virtual bool find(int) const=0;
size_t size() const;
bool empty() const;
bool full() const;
void output(std::ostream& out) const;
friend std::ostream& operator << (std::ostream&, const ListType&);
protected:
int *items;
size_t capacity;
size_t count;
};
#endif // LISTTYPE_H_INCLUDED
here is UListType.h:
#ifndef ULISTTYPE_H_INCLUDED
#define ULISTTYPE_H_INCLUDED
#include <iostream>
class UListType: public ListType {
public:
UListType(size_t=10);
bool insert(int);
bool erase(int);
bool find(int) const;
};
#endif // ULISTTYPE_H_INCLUDED
here is OListType.h:
#ifndef OLISTTYPE_H_INCLUDED
#define OLISTTYPE_H_INCLUDED
#include <iostream>
class OListType: public ListType {
public:
OListType(size_t=10);
bool insert(int);
bool erase(int);
bool find(int) const;
};
#endif // OLISTTYPE_H_INCLUDED
here is ListType.cpp:
#include "ListType.h"
ListType::ListType (size_t a) {
capacity = a;
count = 0;
items = new int [capacity];
}
ListType::~ListType() {
delete [] items;
}
bool ListType::erase() {
count = 0;
return 0;
}
size_t ListType::size() const {
return (count);
}
bool ListType::empty() const {
return (count == 0);
}
bool ListType::full() const {
return (count == capacity);
}
void ListType::output(std::ostream& out) const {
for (int i = 0; i < count; i++) {
if (i > 0) {
out << ", ";
}
out << items[i];
}
}
std::ostream& operator << (std::ostream& out, const ListType& my_list) {
my_list.output(out);
return out;
}
here is UListType.cpp
#include "ListType.h"
#include "UListType.h"
UListType::UListType (size_t c): ListType(c) {}
bool UListType::insert(int item) {
if (full()) {
int *newitems;
capacity *=2;
newitems = new int[capacity];
for (size_t i =0; i < count; ++i){
newitems[i] = items[i];
}
delete [] items;
items = newitems;
}
items[count++] = item;
return true;
}
bool UListType::erase(int item) {
bool result = false;
size_t i=0;
while ( i < count && items [i] != item) {
++i;
}
if (i < count) {
items[i] = items[-- count];
result = true;
}
return result;
}
bool UListType::find(int item) const {
size_t i = 0;
while (i < count && items [i] != item) {
++i;
}
return i;
}
here is OListType.cpp
#include "ListType.h"
#include "OListType.h"
OListType::OListType(size_t c): ListType(c) {}
bool OListType::insert(int item) {
size_t i = count;
if (full()) {
int *newitems;
capacity *=2;
newitems = new int[capacity];
while (i > 0 && items[i-1] > item){
newitems[i] = items[i];
}
delete [] items;
items = newitems;
}
items[count++] = item;
return true;
}
bool OListType::erase(int item) {
bool found=false;
size_t i=0, j= count-1, mid;
while (i <= j && !(found)){
mid = (i + j)/2;
if (item < items [mid])
j = mid - 1;
else if (item > items [mid])
i = mid + 1;
found = items [mid] == item;
}
if (found) {
for (i = mid; i < count - 1; ++i) {
items [i] = items [i +1];
}
--count;
}
return found;
}
bool OListType::find (int item) const {
bool found=false;
size_t i=0, j= count-1, mid;
while (i <= j && !(found)){
mid = (i + j)/2;
if (item < items [mid])
j = mid - 1;
else if (item > items [mid])
i = mid + 1;
found = items [mid] == item;
}
return found;
}

#include "ListType.h"
#include "UListType.h"
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
int main()
{
UListType UL;
cout << "How many numbers do you want to put it?" << endl;
int n;
cin >> n;
cout << "All right, enter " << n << " numbers:" << endl;
int x;
for(int k=0; k<n; ++k)
{
cin >> x;
// do something with x
}
return(0);
}

You already have everything you need. Try the following
#include <iostream>
#include "OListType.h"
using namespace std;
int main()
{
OListType list;
int n;
do
{
cout << "Add a number [Y/n]?";
char a;
cin >> a;
if (a != 'n')
{
cin >> n;
list.insert(n);
}
else
{
list.output(cout);
break;
}
}while (1);
return 0;
}

Related

How to fix "Error in `./a.out': corrupted double-linked list:" in C++

My code compiles successfully, but when I try to run it, I keep getting this error: * Error in `./a.out': corrupted double-linked list: 0x00000000021c1280 *
Aborted
This is my VectorDouble.cpp file
#include<bits/stdc++.h>
#include <cstring>
#include "VectorDouble.h"
#include <iostream>
using namespace std;
VectorDouble::VectorDouble() {
cout<<"constructor called"<<endl;
max_count = 50;
arr = new double[this->max_count];
count = 0;
}
VectorDouble::VectorDouble(int max_count_arg) {
max_count = max_count_arg;
arr = new double[max_count_arg];
count = 0;
}
VectorDouble::VectorDouble(const VectorDouble& copy) {
max_count = copy.max_count;
arr = new double[this->max_count];
count = copy.count;
}
VectorDouble::~VectorDouble() {
delete []arr;
}
VectorDouble VectorDouble::operator =(VectorDouble& copy) {
VectorDouble temp(copy.max_count);
for(int i =0; i<=this->count;i++){
temp.arr[i]=copy.arr[i];
}
return temp;
}
bool VectorDouble::operator ==(VectorDouble b) const {
bool isEqual = true;
if(this->count == b.count){
for(int i = 0; i<=this->count; i++){
if(this->arr[i] == b.arr[i]){
isEqual= true;
}
else{
return false;
}
}
}
return isEqual;
}
void VectorDouble::push_back(double num) {
if(this->count+1>this->max_count){
this->max_count *= 2;
VectorDouble temp(2*(this->max_count));
for(int i = 0; i<this->max_count; i++){
temp.arr[i]=this->arr[i+1];
}
temp.arr[count+1] = num;
}
else{
this->arr[count+1]=num;
this->count++;
}
}
int VectorDouble::capacity() {
return this->max_count;
}
int VectorDouble::size() {
return this->count;
}
void VectorDouble::resize(unsigned int size, double defaultVal) {
if(size>(this->count)){
for(int i = this->count; i<size; i++){
this->arr[i] = defaultVal;
}
this->count=size;
}
else{
for(int i = size; i < this->count; i++){
this->arr[i] ='\0';
}
this->count=size;
}
}
void VectorDouble::reserve(unsigned int size) {
if(size>(this->max_count)){
this->max_count = size;
}
}
double VectorDouble::value_at(unsigned int i) {
if(i>(this->count)){
throw std::logic_error("out of bounds");
}
return this->arr[i];
}
void VectorDouble::change_value_at(double newValue, unsigned int i) {
if(i>(this->count)){
throw std::logic_error("out of bounds");
}
this->arr[i]=newValue;
}
ostream& operator<<(ostream& os, const VectorDouble &vd)
{
for(int i = 0; i < vd.count; i++){
os << vd.arr[i] << " ";
}
return os;
}
This is my VectorDouble.h file
#ifndef DYNAMICARRAY_H
#define DYNAMICARRAY_H
#include <iostream>
using namespace std;
class VectorDouble {
public:
int max_count;
int count;
double* arr;
public:
VectorDouble();
VectorDouble(int max_count_arg);
VectorDouble(const VectorDouble& copy);
~VectorDouble();
VectorDouble operator =(VectorDouble& copy);
bool operator ==(VectorDouble b) const;
void push_back(double num);
int capacity();
int size();
void reserve(unsigned int size);
void resize(unsigned size, double defaultVal = 0.0);
double value_at(unsigned int i);
void change_value_at(double newValue, unsigned int i);
friend ostream& operator<<(ostream& os, const VectorDouble &vd);
// DO NOT CHANGE THE FOLLOWING LINE OF CODE. It is for the testing framework
// DO NOT IMPLEMENT THE FOLLOWING FUNCTION. It is implemented by the testing framework
friend int reserved_driver_main();
};
#endif
This is my main.cpp file
#include <iostream>
#include "VectorDouble.h"
using namespace std;
int user_main() {
// test 1, verify that default constructor initializes max_count
VectorDouble v;
if (v.max_count == 50)
{
std::cout << "1.1. default constructor: max_count = 50; test passed" << std::endl;
}
else
{
std::cout << "1.1. default constructor: max_count != 50; test failed" << std::endl;
}
return 0;
}

[C++]Sorting objects by class member's value

In the code shown below, in the function void printExpensiveThanT(..) i'm supposed to print out the destination, distance and the price for the offers which are more expensive than the offer T in the function, sorted in ascending order by the distance value.
I'm not sure what should i use to sort them, i experimented something with vectors but it didn't work out so i deleted it.
Any help would be appreciated.
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
class Transport {
protected:
char destination[100];
int basePrice;
int distance;
public:
Transport() {}
Transport(char *destination, int basePrice, int distance) {
strcpy(this->destination, destination);
this->basePrice = basePrice;
this->distance = distance;
}
virtual ~Transport() {}
virtual int priceTransport() = 0;
friend bool operator<(const Transport &t1, const Transport &t2) {
return t1.distance<t2.distance;
}
int getDistance(){ return distance; }
char *getDestination() { return destination; }
int getPrice() { return basePrice; }
};
class AutomobileTransport : public Transport {
private:
bool ifDriver;
public:
AutomobileTransport() {}
AutomobileTransport(char *destination, int basePrice,int distance, bool ifDriver) : Transport(destination,basePrice,distance) {
this->ifDriver = ifDriver;
}
void setIfDriver(bool ifDriver) {
this->ifDriver = ifDriver;
}
bool getIfDriver() {
return ifDriver;
}
int priceTransport() {
if(ifDriver) {
basePrice+=basePrice*20/100;
}
return basePrice;
}
friend bool operator<(const AutomobileTransport &a1, const AutomobileTransport &a2) {
return a1.distance<a2.distance;
}
};
class VanTransport: public Transport {
private:
int passengers;
public:
VanTransport() {}
VanTransport(char *destination, int basePrice, int distance, int passengers) : Transport(destination, basePrice, distance) {
this->passengers = passengers;
}
void setPassengers(int passengers) {
this->passengers = passengers;
}
int getPassengers() {
return passengers;
}
int priceTransport() {
for(int i = 0; i < passengers; i++) {
basePrice-=200;
}
return basePrice;
}
friend bool operator<(const VanTransport &k1, const VanTransport &k2) {
return k1.distance<k2.distance;
}
};
void printExpensiveThanT(Transport **offers,int n,AutomobileTransport &T) {
Transport *tmp;
for(int i = 0; i <= n; i++){
if(offers[i]->priceTransport() > T.priceTransport())
cout<<offers[i]->getDestination()<<" "<<offers[i]->getDistance()<<" "<<offers[i]->getPrice()<<endl;
}
}
int main() {
char destination[20];
int type,price,distance,passengers;
bool driver;
int n;
cin>>n;
Transport **offers;
offers=new Transport *[n];
for (int i=0; i<n; i++) {
cin>>type>>destination>>price>>distance;
if (type==1) {
cin>>driver;
offers[i]=new AutomobileTransport(destination,price,distance,driver);
} else {
cin>>passengers;
offers[i]=new VanTransport(destination,price,distance,passengers);
}
}
AutomobileTransport at("Ohrid",2000,600,false);
printExpensiveThanT(offers,n,at);
for (int i=0; i<n; i++) delete offers[i];
delete [] offers;
return 0;
}
Since you're dealing with pointers, the easiest thing to do is to use std::vector and std::sort:
#include <vector>
//...
void printExpensiveThanT(Transport **offers, int n, AutomobileTransport &T)
{
std::vector<Transport*> sortedVect;
for (int i = 0; i < n; i++)
{
if (offers[i]->priceTransport() > T.priceTransport())
sortedVect.push_back(offers[i]); // add this item to the vector
}
// sort the vector based on the dereferenced pointers and their respective
// operator <
std::sort(sortedVect.begin(), sortedVect.end(),
[](Transport* left, Transport* right) { return *left < *right; });
// print out the values
for (auto it : sortedVect)
cout << (*it).getDestination() << " " << (*it).getDistance() << " " << (*it).getPrice() << "\n";
}
Also, your original code looped one more than it should (i <= n was wrong).
Edit:
If your compiler doesn't support the C++ 11 syntax, here is an alternate solution:
#include <vector>
//...
bool Sorter(Transport* left, Transport* right)
{ return *left < *right; }
void printExpensiveThanT(Transport **offers, int n, AutomobileTransport &T)
{
std::vector<Transport*> sortedVect;
for (int i = 0; i < n; i++)
{
if (offers[i]->priceTransport() > T.priceTransport())
sortedVect.push_back(offers[i]); // add this item to the vector
}
// sort the vector based on the dereferenced pointers and their respective
// operator <
std::sort(sortedVect.begin(), sortedVect.end(), Sorter);
// print out the values
std::vector<Transport*>::iterator it = sortedVect.begin();
while (it != sortedVect.end())
{
cout << (*it).getDestination() << " " << (*it).getDistance() << " " << (*it).getPrice() << "\n";
++it;
}
}

Building a 2D array class from a 1D array class in C++

in my C++ class we are finally getting conceptually fairly deep (well, relatively!) and I'm struggling with building a class from a previous class.
Here is my first class header, which builds partially filled array objects. To my knowledge, it is fully functional:
#ifndef PARTIALARRAY_H
#define PARTIALARRAY_H
#include <iostream>
#include <string.h>
using namespace std;
typedef int ITEM_TYPE;
ITEM_TYPE const MAX = 50;
class PartialArray
{
public:
//-----------------------------------------ctors:-----------------------------------------
PartialArray();
PartialArray(const int init[], int used);
//-----------------------------------------member functions:-----------------------------------------
void PrintArray();
int Search(ITEM_TYPE key);
int Append(ITEM_TYPE appendMe);
int ShiftRight(int shiftHere);
int ShiftLeft(int shiftHere);
int InsertBefore(ITEM_TYPE insertThis, int insertHere);
int InsertAfter(ITEM_TYPE insertThis, int insertHere);
int Delete(int deleteHere);
void DeleteRepeats();
int NumUsed();
void Sort();
void Reverse();
string ErrorDescr(int failCode);
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& operator [] (ITEM_TYPE x);
private:
//-----------------------------------------member vars:-----------------------------------------
ITEM_TYPE a[MAX];
int numUsed;
};
#endif // PARTIALARRAY_H
And here are the class functions:
#include "partialarray.h"
#include <iostream>
#include <string.h>
using namespace std;
//-----------------------------------------ctors:-----------------------------------------
PartialArray::PartialArray()
{
numUsed=0;
}
PartialArray::PartialArray(const int init[], int used)
{
numUsed = used;
for(int i=0; i<numUsed; i++)
{
a[i]=init[i];
}
}
//-----------------------------------------member functions:-----------------------------------------
//Prints the array up to its last used element
void PartialArray::PrintArray()
{
for(int i=0; i<numUsed; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
//Searches the array for a particular value and returns the index at which the value first appears
int PartialArray::Search(ITEM_TYPE key)
{
for(int i=0; i<numUsed; i++)
{
if(a[i]==key)
return i;
}
return -1;
}
//Takes a number and appends it to the end of the array after the last interesting element
int PartialArray::Append(ITEM_TYPE appendMe)
{
if(numUsed<MAX)
a[numUsed++] = appendMe;
else
return 1;
return 0;
}
//Shifts all elements of the array to the right starting at a particular index
int PartialArray::ShiftRight(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[numUsed-1];
for(int i=numUsed; i>=shiftHere; i--)
{
a[i] = a[i-1];
}
a[shiftHere] = save;
return 0;
}
else
return 2;
}
//Shifts all elements of the array to the left starting at a particular index
int PartialArray::ShiftLeft(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[shiftHere];
for(int i=shiftHere; i<numUsed; i++)
{
a[i] = a[i+1];
}
a[numUsed-1] = save;
return 0;
}
else
return 2;
}
//Takes a number and a position and inserts the number before that position in the array shifting the elements to the right
int PartialArray::InsertBefore(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else
{
numUsed++;
ShiftRight(insertHere);
a[insertHere] = insertThis;
}
return 0;
}
//Takes a number and a position and inserts the number after that position in the array shifting the elements to the right
int PartialArray::InsertAfter(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else if(numUsed>=MAX)
return 1;
else
{
numUsed++;
ShiftRight(insertHere+1);
a[insertHere+1] = insertThis;
}
return 0;
}
//Takes a position and removes that item from the array, shifting all the elements to the left
int PartialArray::Delete(int deleteHere)
{
if(deleteHere <= numUsed)
{
ShiftLeft(deleteHere);
numUsed--;
return 0;
}
else
return 2;
}
//Deletes repeated elements in the array and replaces the with 0
void PartialArray::DeleteRepeats()
{
for(int i=0;i<numUsed;i++)
{
ITEM_TYPE n=a[i];
for(int j=i+1; j<numUsed;j++)
{
if(n == a[j])
{
Delete(j);
j--;
}
}
}
}
//Returns number of interesting elements in the array
int PartialArray::NumUsed()
{
return numUsed;
}
//Utilizes a bubble sort algorithm
void PartialArray::Sort()
{
bool swap = true;
int j = 0;
int save;
while (swap==true)
{
swap = false;
j++;
for (int i = 0; i < numUsed - j; i++)
{
if (a[i] > a[i + 1])
{
save = a[i];
a[i] = a[i + 1];
a[i + 1] = save;
swap = true;
}
}
}
}
void PartialArray::Reverse()
{
for(int i=0;i<numUsed-1;i++)
{
ITEM_TYPE save = a[numUsed-1];
ShiftRight(i);
a[i] = save;
}
}
//Returns the appropriate error description for a particular fail code
string PartialArray::ErrorDescr(int failCode)
{
switch(failCode)
{
case -1:
return "ERROR: item not found";
break;
case 1:
return "ERROR: array is full";
break;
case 2:
return "ERROR: unused index";
break;
default:
return "UNKNOWN ERROR";
break;
}
}
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& PartialArray::operator [](ITEM_TYPE x)
{
return a[x];
}
Now, here is where things have gotten tricky. To build the two dimensional array class, I'm supposed to create an array of arrays. I'm at a loss as to how I should go about this, and after tinkering and googling for a few hours I've only become more confused. Specifically, the <<, [], and [](constant version) operators and the TwoDArray constructor have thrown me for a loop, and I'm stuck without much sense of what to do next. Here is the TwoD header file:
#ifndef TWODARRAY_H
#define TWODARRAY_H
#include "partialarray.h"
#include <iostream>
#include <string.h>
typedef int ITEM_TYPE;
class TwoDArray
{
friend ostream& operator << (ostream &outs, const TwoDArray& printMe);
public:
//ctors:
TwoDArray();
//member functions:
//PartialArray& operator [](int index); //[ ] operator for the TwoDArray object
//PartialArray operator [](int index) const; //[ ] operator for the TwoDArray object (const version)
int Append(int appendMe, int row);
int InsertBefore(int insertMe, int row, int column);
int InsertAfter(int insertMe, int row, int column);
int Delete(int row, int column);
bool Search(ITEM_TYPE key, int &row, int &column);
private:
//member vars:
PartialArray a[MAX];
};
#endif // TWODARRAY_H
And this is what I've tried to define thus far:
TwoDArray::TwoDArray()
{
const int array0[]= {0};
PartialArray array(array0, MAX);
}
ostream& operator << (ostream &outs, const TwoDArray& printMe)
{
for(int i=0;i<MAX;i++)
{
outs << printMe.a[i];
}
return outs;
}
Ideally, the << operator will print an m by n array of items.

Cref postincrementation in Map definition

So I have such definition on map class on vector, it works good except for post-incrementation, which doesn't work as it should. You can see in example that variable a should be equal to 10 (post-incremented after assignment). But it's equal to 11. I have no idea how to fix that.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template<class T>
class Map {
class Cref {
friend class Map;
Map& m;
string key;
T value;
public:
operator double() {
return m.read(key);
};
Map::Cref & operator=(double num) {
m.write(key, num);
return *this;
};
Map::Cref & operator++(int) {
Cref c(*this);
m.increment(key, value);
return c;
}
Cref(Map& m, string a)
: m(m),
key(a) {};
};
public:
class Unitialized {};
struct Record {
string key;
T value;
};
vector<Record> data;
Map() {}
~Map() {}
bool ifexist(string k) {
for (int i = 0; i < data.size(); i++) {
if (data.at(i).key == k)
return 1;
}
return 0;
}
Cref operator[](string key) {
return Map::Cref( * this, key);
}
private:
void increment(string key, T value) {
if (ifexist(key) == 0) {
throw Unitialized();
}
for (int i = 0; i < data.size(); i++) {
if (data.at(i).key == key)
data.at(i).value += 1;
}
}
void write(string key, T value) {
if (ifexist(key) == 1) {
cout << "Element already exist" << endl;
return;
}
Record r;
r.key = key;
r.value = value;
data.push_back(r);
}
double read(string key) {
if (ifexist(key) == 0) {
throw Unitialized();
}
for (int i = 0; i < data.size(); i++) {
if (data.at(i).key == key)
return data.at(i).value;
}
return 0;
}
};
int main(int argc, char** argv) {
Map<int> m;
m["ala"] = 10;
int a = 0;
a = m["ala"]++;
cout << a << endl;
try {
cout << m["ala"] << endl;
cout << m["ola"] << endl;
} catch (Map<int>::Unitialized&) {
cout << "Unitialized element" << endl;
}
return 0;
}
Yes, I already fixed that, overloading of ++ operator should look like that :
T operator ++(int)
{
T ret = m.read(this->key);
m.increment(key, value);
return ret;
}
This fixes everything.

C++ Undefined reference to List<int>::GetCount() const [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 9 years ago.
I am writing a simple data structure library, while I met some problems.
I wrote three files. collections.h is the header file, collections.cpp is to implement the methods declared in header file, main.cpp is for test. But compile error occurs:
Undefined reference to List::GetCount() const;
Undefined reference to List::IsEmpty() const;
Undefined reference to List::Add(int);
...// And so on.
I provide my code below, where is the problem?
collections.h:
#ifndef COLLECTIONS_H
#define COLLECTIONS_H
#include <windows.h>
#include <stdexcept>
template<typename T>
class ISequenceList
{
protected:
ISequenceList() { }
public:
virtual int GetCount() const = 0;
virtual bool IsEmpty() const = 0;
virtual void Add(T item) = 0;
virtual void AddRange(const T *items, int length) = 0;
virtual T &ElementAt(int index);
virtual bool InsertAt(T item, int index);
virtual bool Remove(T item) = 0;
virtual bool RemoveAt(int index) = 0;
virtual bool Contains(T item) = 0;
};
template<typename T>
class List : public ISequenceList<T>
{
private:
int _count;
int _capacity;
T *_array;
void ExpandCapacity();
public:
List(int capacity = 100)
{
if (capacity <= 0)
std::__throw_invalid_argument("The capcity can't be 0 or below.");
this->_count = 0;
this->_capacity = capacity;
this->_array = (T*)malloc(_capacity* sizeof(T));
}
List(const List &other)
{
if (this == other)
return;
this->_count = other->_count;
this->_capacity = other->_capacity;
free(_array);
this->_array = other->_array;
}
List &operator=(const List &other)
{
this = other;
}
~List()
{
if (_array)
free(_array);
}
int GetCount() const;
bool IsEmpty() const;
T &ElementAt(int index);
void Add(T item);
void AddRange(const T *items, int length);
bool InsertAt(T item, int index);
bool Remove(T item);
bool RemoveAt(int index);
bool Contains(T item);
};
#endif
collections.cpp:
#include "collections.h"
template<typename T>
void List<T>::ExpandCapacity()
{
T *temp = this->_array;
this->_array = (T*)malloc((this->_capacity << 1) * sizeof(T));
memcpy(this->_array, temp, this->_capacity * sizeof(T));
this->_capacity = this->_capacity << 1;
free(temp);
}
template<typename T>
int List<T>::GetCount() const
{
return this->_count;
}
template<typename T>
bool List<T>::IsEmpty() const
{
return this->_count == 0;
}
template<typename T>
void List<T>::Add(T item)
{
this->_array[_count] = item;
_count++;
if (_count == _capacity)
this->ExpandCapacity();
}
template<typename T>
void List<T>::AddRange(const T *items, int length)
{
if (length <= 0)
std::__throw_invalid_argument("The length can't be 0 or below.");
if (!items)
std::__throw_invalid_argument("The items can't be null");
int totalLength = this->_count + length;
if (totalLength >= this->_capacity)
{
T *temp = this->_array;
this->_array = (T*)malloc((totalLength << 1) * sizeof(T));
memcpy(_array, temp, this->_capacity);
free(temp);
}
this->_array += this->_capacity;
memcpy(_array, items, length * sizeof(T));
this->_capacity = totalLength << 1;
this->_count += length;
}
template<typename T>
T &List<T>::ElementAt(int index)
{
if (index < 0 || index >= _count )
std::__throw_invalid_argument("The index is out of bound.");
return _array[index];
}
template<typename T>
bool List<T>::InsertAt(T item, int index)
{
if (index < 0 || index > _count)
return false;
if (index == _count)
{
this->Add(item);
return true;
}
for (int i = _count; i > index; i--)
{
_array[i] = _array[i - 1];
}
_array[index] = item;
_count++;
if (_count == _capacity)
this->ExpandCapacity();
return true;
}
template<typename T>
bool List<T>::Remove(T item)
{
for (int i = 0; i < _count; i++)
{
if (_array[i] == item)
{
for (int j = i; j < _count; j++)
{
_array[j] = _array[j + 1];
}
_count--;
return true;
}
}
return false;
}
template<typename T>
bool List<T>::RemoveAt(int index)
{
if (index < 0 || index >= _count)
return false;
for (int j = index; j < _count; j++)
{
_array[j] = _array[j + 1];
}
_count--;
return true;
}
template<typename T>
bool List<T>::Contains(T item)
{
for (int i = 0; i < _count; i++)
{
if (_array[i] == item)
return true;
}
return false;
}
main.cpp:
#include "collections.h"
#include <iostream>
int main()
{
List<int> *seqList = new List<int>();
seqList->Add(5);
int arr[100] = {0};
seqList->AddRange(arr, 50);
seqList->ElementAt(5) = 111;
seqList->InsertAt(100, 15);
seqList->Remove(50);
seqList->ElementAt(44) = 44;
seqList->RemoveAt(44);
if (seqList->Contains(111))
std::cout << "Yes" << std::endl;
for (int i = 0; i < seqList->GetCount(); i++)
{
std::cout << seqList->ElementAt(i) << "\t";
}
return 0;
}
I have defined all the methods in List, but why can't the complier recognize? Where is the problem? Thanks for anyone who help me..
Note: my ide is Code::Blocks
Implementation of the template functions must be in a header; it can't be in a separate source file. The compiler needs to see it at the point where the template is used and its arguments become known.