Search code examples
c++data-structuresfriend

Having errors while trying to use friend


Im trying to create a MultiListADT and having trouble writing code that will print out the list. Im trying to make a function in one class a friend of another so I can then create a way that will allow me to print out the list. However im having trouble getting the friend function to work. Im only going to include parts of the code so it doesnt get too long. The error I get is error C2039 'PrintList' is not a member of 'MultiListADT. Im new to using friends so im not quite sure how I can make this work.

MultiListADT.h

#include <iostream>
#include <fstream>
#include "NodeADT.h"
#include <string>

using namespace std;



template <class TYPE,int threads>
class MultiListADT
{
public:
/** Constructor **/
MultiListADT();

/** Destructor **/
~MultiListADT();

/** Declare accessors (observers) **/
void ResetListForward(int=0);
void ResetListBackward(int=0);
bool IsEmpty(int=0);
int LengthIs(int=0);
bool Search(TYPE, bool=true,int=0);
void GetNextItem(TYPE &,int i=0);
void GetPreviousItem(TYPE &,int=0);
int GetInfo(int=0);
int findCountry(TYPE,int=0);
int findContinent(TYPE,int=0);
int findYear(TYPE,int=0);
friend void PrintList(MultiListADT<string,100>&,int=0);

/** Declare mutators (transformers) **/
void MakeEmpty();
void AddToFront(TYPE,int=0);
void AddToRear(TYPE,int=0);
void InsertInOrder(TYPE,int=0);
void Delete(TYPE);
void Sort();



private:
NodeADT<TYPE,threads>* head[threads];
NodeADT<TYPE,threads>* tail[threads];
int length;
string indices[threads];
NodeADT<TYPE,threads>* currentNode[threads];
};

template <class TYPE, int threads>
void MultiListADT<string,100>::PrintList(MultiListADT<string,100> &theList,int i)
{
     //code for reading out list
}

NodeADT.h

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

const int null = 0;

template<class TYPE, int threads>
class MultiListADT;

template <class TYPE, int threads>
class NodeADT
{
public:
NodeADT();
NodeADT(TYPE);
~NodeADT();
TYPE getInfo();
NodeADT<TYPE, threads>* getPrevious(int=0);
NodeADT<TYPE, threads>* getNext(int=0);
void setNext(NodeADT<TYPE, threads>*,int=0);
void setPrevious(NodeADT<TYPE, threads>*,int=0);
bool Search(TYPE, bool=true,int=0);
void AddToFront(TYPE item, int=0);
void AddToRear(TYPE item,int=0);
void InsertInOrder(TYPE, int=0);
bool Delete(TYPE,int=0);
int findCountry(TYPE,int=0);
int findContinent(TYPE,int=0);
int findYear(TYPE,int=0);
bool Comparelist(TYPE,TYPE,int=0);
friend void PrintList(MultiListADT<TYPE,threads>&,int=0);
private:
TYPE info;
NodeADT<TYPE, threads>* prev[threads];
NodeADT<TYPE, threads>* next[threads];
};

Solution

  • First of all, is PrintList intended to be a member or non-member? You have this:

    friend void PrintList(MultiListADT<string,100>&,int=0);
    

    ... yet you're trying to define it like a method:

    template <class TYPE, int threads>
    void MultiListADT<string,100>::PrintList(MultiListADT<string,100> &theList,int i)
    {
         //code for reading out list
    }
    

    Note that this should read:

    template <class TYPE, int threads>
    void MultiListADT<TYPE,threads>::PrintList(MultiListADT<TYPE,threads> &theList,int i)
    {
         //code for reading out list
    }
    

    If it's a method in MultiListADT, then you do not need to declare it as a friend there. Just define it as a normal method. If you want to access that method from NodeADT, you can make the MultiListADT class a friend if that method is private. However, it looks to me like you are trying to make it public in which case you don't need friends at all.

    Finally, as advice, I recommend you try to find ways to avoid friends when possible. Think hard about the design and take a look at standard containers like std::vector, std::list, etc. These allow us to print their contents without any kind of friends involved which access the internals of these aggregates. How? These collections provide iterators, a very important concept that seems to be lacking in your list design.

    By providing iterators, you can actually implement pretty much anything you can imagine using the list without ever being tempted to access any internals.