#ifndef ARRAYLIST_H
#define ARRAYLIST_H

#include <iostream>
using namespace std;

template <class ItemType>
class ArrayList
{
public:
	enum SortOrder  {ASCENDING, DESCENDING};

private:
	typedef ItemType* pItemType;
	typedef pItemType* ppItemType;

	ppItemType items;
	size_t count;

	// Finds the index of the next item in order.
	size_t FindNextIndex(const int start, const SortOrder order) const;

	// Swaps the two items at the given indices.
	void SwapItems(const size_t index1, const size_t index2);

	// Copies the parameter list.
	void CopyList(const ArrayList<ItemType>& copyArrayList);

	// Deletes all allocated memory.
	void DeleteList();

	// Displays the items in the array, one per line.
	friend ostream& operator <<(ostream& out, const ArrayList<ItemType>& anArrayList);

public:
	// Sets items to NULL and count to 0.
	ArrayList();

	// Initializes object to the parameter object.
	ArrayList(const ArrayList<ItemType>& copyArrayList);

	// Deletes all allocated memory.
	~ArrayList();

	// Assigns the parameter object to the current object.
	ArrayList operator =(const ArrayList<ItemType>& assignArrayList);

	// Adds and item and returns added item. Array is resized by one.
	pItemType Add(pItemType anItem);

	// Removes the item at the given index. Array is resize by one.
	void RemoveItemAtIndex(const size_t index);

	// Returns the item at the given index.
	pItemType ItemAtIndex(const size_t index) const;

	// Returns the size of the array.
	size_t Count() const;

	// Sorts array in either ascending/descending order.
	void Sort(const SortOrder order);
};


// Finds the index of the next item in order.
template <class ItemType>
size_t ArrayList<ItemType>::FindNextIndex(const int start, const SortOrder order) const
{
	size_t next = start;

	if(order == ASCENDING)
	{
		for(size_t i = start+1; i < count; i++)
		{
			if(*items[next] > *items[i])
				next = i;
		}
	}
	else
	{
		for(size_t i = start+1; i < count; i++)
		{
			if(*items[next] < *items[i])
				next = i;
		}
	}
	return next;
}

// Swaps the two items at the given indices.
template <class ItemType>
void ArrayList<ItemType>::SwapItems(const size_t index1, const size_t index2)
{
	ItemType temp = *items[index1];
	*items[index1] = *items[index2];
	*items[index2] = temp;
}

// Copies the parameter list.
template <class ItemType>
void ArrayList<ItemType>::CopyList(const ArrayList& copyArrayList)
{
	count = copyArrayList.Count();
	items = new pItemType[copyArrayList.Count()];
	for (size_t i = 0; i < count; i++)
	{
		items[i] = new ItemType(*copyArrayList.ItemAtIndex(i));
	}
}

// Deletes all allocated memory.
template <class ItemType>
void ArrayList<ItemType>::DeleteList()
{
	for(size_t i = 0; i < Count(); i++)
	{
		delete items[i];
		items[i] = NULL;
	}
	delete items;
	items = NULL;
}

// Displays the items in the array in one line.
template <class ItemType>
ostream& operator <<(ostream& out, const ArrayList<ItemType>& anArrayList)
{
	for(size_t i = 0; i < anArrayList.Count(); i++)
	{
		out << *anArrayList.items[i] << " ";
	}
	return (out);
}

// Sets items to NULL and count to 0.
template <class ItemType>
ArrayList<ItemType>::ArrayList()
{
	items = NULL;
	count = 0;
}

// Initializes object to the parameter object.
template <class ItemType>
ArrayList<ItemType>::ArrayList(const ArrayList& copyArrayList)
{
	CopyList(copyArrayList);
}

// Deletes all allocated memory.
template <class ItemType>
ArrayList<ItemType>::~ArrayList()
{
	DeleteList();
}

// Assigns the parameter object to the current object.
template <class ItemType>
ArrayList<ItemType> ArrayList<ItemType>::operator =(const ArrayList<ItemType>& assignArrayList)
{
	if(items != assignArrayList.items)
	{
		DeleteList();
		CopyList(assignArrayList);
	}
	return (*this);
}

// Adds and item and returns added item. Array is resized by one.
template <class ItemType>
typename ArrayList<ItemType>::pItemType ArrayList<ItemType>::Add(pItemType anItem)
{
	if(items == NULL)
	{
		count++;
		items = new pItemType[count];
		items[count-1] = anItem;
	}
	else
	{
		ArrayList temp;	
		temp.count = Count()+1;
		temp.items = new pItemType[temp.count];
		for(size_t i = 0; i < temp.count-1; i++)
		{
			temp.items[i] = new ItemType(*(*this).ItemAtIndex(i));
		}
		temp.items[temp.count-1] = new ItemType(*anItem);
		(*this).DeleteList();	
		(*this).CopyList(temp);
	}
	return items[count-1];
}

// Removes the item at the given index. Array is resize by one.
template <class ItemType>
void ArrayList<ItemType>::RemoveItemAtIndex(const size_t index)
{
	for(size_t i = index; i < Count(); i++)
	{
		items[i] = items[i+1];
	}
	count--;
}

// Returns the item at the given index.
template <class ItemType>
typename ArrayList<ItemType>::pItemType ArrayList<ItemType>::ItemAtIndex(const size_t index) const
{
	return items[index];	
}

// Returns the size of the array.
template <class ItemType>
size_t ArrayList<ItemType>::Count() const
{
	return count;
}

// Sorts array in either ascending/descending order.
template <class ItemType>
void ArrayList<ItemType>::Sort(const SortOrder order)
{
	for(size_t i = 0; i < Count(); i++)
	{
		SwapItems(i, FindNextIndex(i, order));
	}
}

#endif
Error	1	error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class ArrayList<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$ArrayList@H@@@Z) referenced in function _main	p04.obj

Any help?

I used VC++ 2010 Express and did not get that link error. All I added was this to the bottom of what you posted (after the #endif)

int main()
{
    ArrayList<int> a;
}

We were handed a driver to test our program:

#include "ArrayList.h"
#include <iostream>

using namespace std;


int main()
{
	ArrayList<int> arrayList;

	// Add five numbers to the list.
	arrayList.Add( new int(10) );
	arrayList.Add( new int(1) );
	arrayList.Add( new int(4) );
	arrayList.Add( new int(8) );
	arrayList.Add( new int(3) );

	// List the arrayList.
	cout << "Original arrayList:" << endl;
	cout << arrayList << endl << endl;

	// Sort the arrayList.
	arrayList.Sort(ArrayList<int>::ASCENDING);

	cout << "Sorted arrayList in ascending order:" << endl;
	cout << arrayList << endl << endl;

	// Test the copy constructor and =() method.
	ArrayList<int> copyList(arrayList);
	ArrayList<int> assignList;


	// Remove one value from the copy list.
	copyList.RemoveItemAtIndex(4);

	// List the arrayList.
	cout << "Original arrayList (should be the same as above):" << endl;
	cout << arrayList << endl << endl;

	// List the copyList.
	cout << "CopyList (last item removed):" << endl;
	cout << copyList << endl << endl;

	assignList = arrayList;
	assignList.Sort(ArrayList<int>::DESCENDING);

	// List the arrayList.
	cout << "Original arrayList (should be the same as above):" << endl;
	cout << arrayList << endl << endl;

	// List the assignList.
	cout << "Sorted assignList in descending order:" << endl;
	cout << assignList;
	cout << endl << endl;

	return (0);
}// end main()

Sorry, beats me why it doesn't link. Someone else with better knowledge of templates than I will have to figure this one out. I added <fstream> and <ostream> but neither of them helped. I also had the compiler generate the *.i file (a file that the preprocessor generates) but that didn't show up anything useful either.

Edited 6 Years Ago by Ancient Dragon: n/a

I think I narrowed it down to the overloaded << operator. Not sure what the syntax should be though.

Yes it was the driver that caused the link error and the overloadede << operator. I also made the class friend line public, but that didn't fix it either.

This article has been dead for over six months. Start a new discussion instead.