I have a base class called ModelFile

I have derived classes called ObjFile and VtkFile that I would like both to use << from ModelFile.

However, since << is an external function,

ostream & operator << (ostream &output, const ModelFile &Model)
	{
		output << "Num Vertices: " << Model.NumVertices() << endl
				<< "Num Triangles: " << Model.NumTriangles() << endl;
		return output;
	}

The compiler doesn't know about

ostream & operator << (ostream &output, const ObjFile &Obj)

Is there a way to do this?

Thanks,
Dave

To my knowledge, the only way to use the same version of << for both classes would be if they output exactly the same information about both classes. In that case you might be able to put the << operator in a base class and then let both classes inherit the same << operator from the base class.

struct base
int data;
void printData() {cout << data;}

struct V : public base
string name;
void printName() {cout << name;}

struct C : public base
char gender;
void showGender() {cout << gender;}

V v;
v.name = "me";
v.data = 1;

C c;
c.gender = 'F';
c.data = -9999;

v.printData();
c.printData();

Each V object and each C object inherit an int member from base called data and a function from base to display that value. However, no base object contains either a name or a gender or a method to display that information. The printData() method cannot be modified in any derived class for it's own specifications unless you were to declare it with the keyword virtual. Even then, the function declaration in the derived classes needs to be the same, although the implementation can be different.

right, but the problem is that the << operator is not a member function, so it is not inherited, right?

struct base
{
  virtual std::ostream& write( std::ostream& stm ) const = 0 ;
  // ...
};

inline  std::ostream& operator<< ( std::ostream& stm, const base& object )
{
  return object.write( stm ) ; // polymorphic
}

// ----------------------------------------------------------------------------------------------------

struct derived : base
{
  // override
  virtual std::ostream& write( std::ostream& stm ) const
  {
    // write object out to stream
    return stm ;
  }
  // ...
};

Copy, paste, compile and run the following program and see if it meets your criteria of using the same << for different classes derived from a common base class. The program is obviously based on the code snippet from vijayan21, whom I applaud for the nifty snippet!

Hopefully this works not just because of some quirk in my compiler (VC++ 6), though I respect vijayan21 enough to expect it to work with any reasonable compiler.

#include <iostream>

using namespace std;

struct base
{  
  virtual std::ostream& write( std::ostream& stm ) const = 0;  
  // ... 
};

inline  std::ostream& operator<< ( std::ostream& stm, const base& object )
{  
  return object.write( stm ) ; // polymorphic
} 

// ---------------------------------------------------------------------------------------------------- 
struct derived : base
{  
  // override  
  virtual std::ostream& write( std::ostream& stm ) const  
  {    
    // write object out to stream   
    stm << data << endl;
    return stm ;  
  } 

  int data;
};

//..................................................
struct anotherDerived : base
{
  // override  
  virtual std::ostream& write( std::ostream& stm ) const  
  {    
    // write object out to stream   
    stm << data << " and " << i << endl;
    return stm ; 
  } 

  double data;
  int i;
};
 
int main()
{
   derived d;
   d.data = 44;
   cout << d << endl;

   anotherDerived ad;
   ad.data = 9.9999;
   ad.i = -687;
   cout << ad << endl;

   return 0;
}

Note there's only a single declaration and definition of the << operator which works for all classes derived from the base class for which it was written. To me it fits the following scenario as posted in your first post, but you can be the final judge.

>>I have a base class called ModelFile. I have derived classes called ObjFile and VtkFile that I would like both to use << from ModelFile.

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