Thread: A problem with some code

  1. #1
    Registered User
    Join Date
    Feb 2003
    Posts
    76

    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

  2. #2
    Registered User
    Join Date
    Jan 2003
    Posts
    648
    I see a problem:

    Code:
    Output << "[" << i << "] " << *theArray[i] << endl;
    I don't think you need the * in that statement...... try that, who knows??

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    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.

  4. #4
    Veni Vidi Vice
    Join Date
    Aug 2001
    Posts
    343
    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!

  5. #5
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    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.

  6. #6
    Veni Vidi Vice
    Join Date
    Aug 2001
    Posts
    343
    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
    Last edited by ripper079; 02-12-2003 at 05:03 AM.

  7. #7
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    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.

  8. #8
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    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?

  9. #9
    Veni Vidi Vice
    Join Date
    Aug 2001
    Posts
    343
    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?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code problem
    By sybariticak47 in forum C++ Programming
    Replies: 9
    Last Post: 02-28-2006, 11:50 AM
  2. Problem with game code.
    By ajdspud in forum C++ Programming
    Replies: 5
    Last Post: 02-14-2006, 06:39 PM
  3. problem with selection code
    By DavidP in forum Game Programming
    Replies: 1
    Last Post: 06-14-2004, 01:05 PM
  4. Replies: 5
    Last Post: 12-03-2003, 05:47 PM
  5. Help with code for simple Y2K problem
    By Mule in forum C++ Programming
    Replies: 3
    Last Post: 03-06-2003, 12:53 AM