-
A problem with some code
Im not one for wrting questions on these things much but this one is bugging me.
// listing 19.3 - Non-Template Friend Classes and Functions
Code:
#include <iostream.h>
const int DefaultSize = 10;
// declare a simple Amimal class so that we can
// create an array of animals
class Animal
{
public:
Animal(int);
Animal();
~Animal() {}
int GetWeight() const { return itsWeight; }
void Display() const { cout << itsWeight; }
private:
int itsWeight;
};
Animal::Animal(int weight):
itsWeight(weight)
{}
Animal::Animal():
itsWeight(0)
{}
template <class T> // declare the template and the parameter
class Array // the class being parameterized
{
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]; }
// accessors
int GetSize() const { return itsSize; }
// Freind Function
friend ostream& operator<< (ostream&,Array<T>&);
private:
T *pType;
int itsSize;
};
// friend function. not a template can only be used
// with int arrays! Intrudes into private data
template <class T>
ostream& operator<< (ostream& Output,Array<T>& theArray)
{
for (int i = 0; i<theArray.GetSize(); i++)
Output << "[" << i << "] " << *theArray[i] << endl; return Output;
}
// implementation follow...
// implement the 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 =
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;
}
// driver program
int main()
{
bool Stop = false; // flag for looping
int offset, value;
Array<int> theArray;
while (!Stop)
{
cout << "Enter an offset (0-9) ";
cout << "and a value. (-1 to stop): ";
cin >> offset >> value;
if (offset < 0)
break;
if (offset > 9)
{
cout << "***Please use values between 0 and 9.***\n";
continue;
}
theArray[offset] = value;
}
cout << "\nHere's the entire array:\n";
cout << theArray << endl;
return 0;
}
I keep getting the error message
C:\WINDOWS\TEMP\ccfmpbgb.o(.text+0x1cb):listin~3.c pp: undefined reference to `operator<<(ostream &, Array<int> &)'
can someone please help me
CODE TAGS added by Hammer
-
I see a problem:
Code:
Output << "[" << i << "] " << *theArray[i] << endl;
I don't think you need the * in that statement...... try that, who knows??
-
Sorry I added that when I was trying to get it to work. even if you take the star out it still says the same error.
-
The problem lies that you need to overload << for the Animal-class. When you use user defined classes (Animal in this case) in your array template you must make sure that the user defined class also overload the << operator or else it wonīt work. Change your Animal class to
Code:
class Animal
{
friend ostream& operator<< (ostream& os, Animal &ani)
{
os << ani.itsWeight;
return os;
}
public:
Animal(int);
Animal();
~Animal() {}
int GetWeight() const { return itsWeight; }
void Display() const { cout << itsWeight; }
private:
int itsWeight;
};
and it should work!
-
Thanks for the help but it still comes up with the same error. You could run the whole thing through the Animal class but then that would take away the point of the template. Anyway I added your code and the same error taks place as before.
-
Hmm that strange. Iīve modified (shortend) your code and it works for me here. Check it out.
Code:
#include <iostream.h>
#include <conio.h>
const int DefaultSize = 10;
class Animal
{
public:
Animal(int);
Animal();
~Animal() {}
int GetWeight() const { return itsWeight; }
void SetWeight(int weight) { itsWeight = weight; }
void Display() const { cout << itsWeight; }
friend ostream& operator<< (ostream& os, Animal &ani)
{
os << ani.itsWeight << endl;
return os;
}
private:
int itsWeight;;
};
Animal::Animal(int weight):
itsWeight(weight)
{
cout << "Animal(int) " << endl;
}
Animal::Animal():
itsWeight(30)
{
cout << "Animal() " << endl;
}
template <class T>
class Test
{
friend ostream& operator<< (ostream& os, Test<T> &object)
{
os << object.itsMember;
return os;
}
public:
Test(){}
T & getObject() {return itsMember;}
private:
T itsMember;
};
int main()
{
/* Default constructor for Tiger isnīt enough we must set the weight manually */
Test<Animal> Tiger;
Tiger.getObject().SetWeight(300);
/* FAT CAT :D, default constructor for Cat */
Test<Animal> Cat;
cout << "Cat weights: " << Cat;
cout << "Tiger weights: " << Tiger;
getch();
return 0;
}
Hopefully I have give you some insights how to solve your problem.
Check in a similair thread also
-
I'll have a look at the weekend when im off because im tired at the moment and it just doesn't make sense. Im sure ill get it at the weekend.
-
I figured it out now. I've been reading a few of my books and it has clarified my understanding of friend classes.
You see the operator << is a friend class of array it does not belong to array. So when you implement it outside the class and put template before it. This is wrong because it does not belong to the template class. Now yours works because your implementation is done within the class.
So if you put my operator << implementation in the array class it complies with no errors. So my next question has to be how would you go about doing the implementation outside the class?
-
Let me guess, you are using MSVC? If you are there is a bug in it with just overloading the << operator outside the class. Download the service pack and the problem should be solved.
Dont show this to Fordy k? :)