inheritance of streams

This is more meant as a brain teaser question, I can easily get around the problem by copying a class and creating two completely separate classes but I'd like to know if anyone has a way to complete the inheritance properly.  Here it goes

I am trying to create some extra functions for the stl stream classes.  In the end I would like to have two classes, MyInputStringStream and MyInputFileStream.  Both classes use the same custom methods that I have created but one is inherited from stringstream and the other from fstream.

The iheritance would look something like this:

              __iostream___
            /           |          \
      fstream MyStream   stringstream
       \            /          \         /
  MyInputFileStream   MyInputStringStream


This is what I have tried writing as class definitions:

class MyStream : virtual public iostream {  /* funct defs here */ }

class MyInputFileStream : public MyStream , public fstream { };
class MyInputStringStream : public MyStream, public stringstream {};

The compilier is finding this ambiguous when making function calls

If i try to change iostream to ios I am unable to define my function new functions which use iostream calls.

I know that if I was not using predefined classes then MyStream would inherit iostream and then fstream and stringstream would each inherit MyStream but that doesn't seem to be an option this time.

Anyone that wants to have fun with inheritance feel free to play around with it.

Thanks,
  gkatz
LVL 3
gkatzAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AxterCommented:
Have you  tried making virtual  the multiple inheritance?

class MyStream : virtual public iostream {  /* funct defs here */ }

class MyInputFileStream : virtual public fstream, public MyStream{ };
class MyInputStringStream : virtual public stringstream, public MyStream{};

0
gkatzAuthor Commented:
sorry the compilier still sees it as being ambiguous
0
AxterCommented:
I'm not getting a compile error.
Are you including all the required headers

#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

class MyStream : virtual public iostream {  /* funct defs here */ };

class MyInputFileStream : virtual public fstream, public MyStream{ };
class MyInputStringStream : virtual public stringstream, public MyStream{};
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

AxterCommented:
FYI:
I think you're better off using a template for this requirement.

Example:
template<class T>
class MyStream : public T {  /* funct defs here */ };

void TestCode()
{
      MyStream<stringstream> MyInputStringStream;
      MyStream<fstream> MyInputFileStream;
}

0
gkatzAuthor Commented:
it's not a compilier error, It's occuring when I try to use the MyInputFileStream class and use one of the iostream functions that applies to it.

in other words

int i;
MyInputFileStream f;
f  >> i;

f >> i causes an error because it is ambiguous.
0
AxterCommented:
If you want to add more detailed functionallity to each type you can also do the following:

template<class T>
class MyStream : public T {  /* funct defs here */ };

class MyInputStringStream : public MyStream<stringstream>{ };
class MyInputFileStream : public MyStream<fstream>{ };

void TestCode()
{
      MyInputStringStream myinputstringstream;
      MyInputFileStream myinputfilestream;
}

0
AxterCommented:
>> f >> i causes an error because it is ambiguous

If you use the template method, that should remove the ambigouity.
0
gkatzAuthor Commented:
That could work, but here's an issue part of the advantage of using the inheritance was to allow functions to exist that coule use either type of stream.  If I use a template then I would need to overload the function rather than just allow the user to pass an object that has a base class of MyStream.

Thanks for the input.  I may try using a template.

gkatz

0
AxterCommented:
>>If I use a template then I would need to overload the function rather than just allow the user to pass an
>>object that has a base class of MyStream.

I'm not sure what you mean by this.

Can you give an example code showing what you would gain via your original method?
0
gkatzAuthor Commented:
an example would be

//not using templates
//this function could accept both MyInputFileStream and  MyInputStringStream
someFunction(MyStream stream) {
   string str;
   stream >> str;
   cout  << str;
}

//using templates
//need two functions
someFunction(MyStream<fstream> stream ){
   string str;
   stream >> str;
   cout  << str;
}

someFunction(MyStream<stringstream> stream ){
   string str;
   stream >> str;
   cout  << str;
}



0
AxterCommented:
For something like that, all you have to do is make your function take iostream type, and it will still work with templates.

Example:
template<class T>
class MyStream : public T {  /* funct defs here */ };

class MyInputStringStream : public MyStream<stringstream>{ };
class MyInputFileStream : public MyStream<fstream>{ };

void someFunction(iostream &stream) {
   string str;
   stream >> str;
   cout  << str;
}

void TestCode()
{
     MyInputStringStream myinputstringstream;
     MyInputFileStream myinputfilestream;
       someFunction(myinputstringstream);
       someFunction(myinputfilestream);
}
0
AxterCommented:
FYI:
If someFunction needs a specific functionallity of MyStream, then you can also make someFunction a template function.

Example:

template<class T>
class MyStream : public T
{
public:
      void foo(){}
};

class MyInputStringStream : public MyStream<stringstream>{ };
class MyInputFileStream : public MyStream<fstream>{ };

template<class T>
void someFunction(T &stream) {
   string str;
   stream.foo();
   stream >> str;
   cout  << str;
}

void TestCode()
{
     MyInputStringStream myinputstringstream;
     MyInputFileStream myinputfilestream;
       someFunction(myinputstringstream);
       someFunction(myinputfilestream);
}

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gkatzAuthor Commented:
True a valid solution.

   Since this is supposed to be used by other programmers I think I will just stick with two separate classes just to make it more transparent to them.  Thanks for all of the ideas.  I was getting pretty annoyed that I could not find a solution.


gkatz

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.