1

This is quite a complicated question. So I have an absolute abstract Base class, and 3 derived classes (A, B, C).

Using the std::ifstream& operator>>(std::ifstream& ifs, Base* a) I have a file that is set up something like this:

A 5 2

B 2 3

Each line starts with a either A, B, C that tells me the type of class I'm getting, then the actual values for the class.

int a, b;
std::string what;
ifs >> what >> a >> b;
if (what == "A")
{
  //create an A class using a, and b.
}

So from the Base operator>> I have to call one of the derived class function where finally 'a' (the Base *) will get either an A, B or C class returned from the funcion, and I'm saving 'a' in a heterogeneous collection.

Is this possible? How do I do this, it feels like I'm just making a circle where I need the Derived class in the Base class and the Base class in the Derived class.

Community
  • 1
  • 1
ptr0x01
  • 627
  • 2
  • 10
  • 25

3 Answers3

1

It probably makes more sense to make a factory function, which could be a static member of Base();

If you want to keep the current structure, I think you can solve it like this:

std::ifstream& operator>>(std::ifstream& ifs, Base* a){
    // remove whatever object you currently have in a
    if(a!=NULL) delete a;

    // standard factory
    // e.g. read what you need to determine the correct derived class 
    // and call its constructor
    int a, b;
    std::string what;
    ifs >> what >> a >> b;
    if (what == "A")
    {
        //create an A class using a, and b.
        a = new A(a,b);
    }
    ...
}

Edit: you may need to use a reference to a Base pointer in the prototype:

std::ifstream& operator>>(std::ifstream& ifs, Base *&a){ ... }
Marc Claesen
  • 16,778
  • 6
  • 27
  • 62
  • To call the derived classes I have to put them above the base class though, and to use the base class in the derived classes I have to put the base above the derived, from my understanding. Wouldn't that cause problems? – ptr0x01 May 05 '13 at 16:30
  • @SaintHUN Maybe you could do something like [forward declaration](http://stackoverflow.com/questions/553682/when-to-use-forward-declaration) if you need? – gongzhitaao May 05 '13 at 16:33
  • Maybe I misunderstand your question, but you can always define classes and their member functions prior to implementing them. The implementation of member functions of a base class can use derived classes if necessary. I don't see any problems in this particular case since you are merely constructing a derived object to a base pointer. – Marc Claesen May 05 '13 at 16:38
  • Thank you this seems interesting. – ptr0x01 May 05 '13 at 16:38
0

Really need a derived class? Based on the information and code you provided, I don't see what the difference between 'A', 'B' and 'C' except for its type, so I came up with the following code:

#include <string>
#include <iostream>
using namespace std;

class foo {
public:
    foo(int aa = 0, int bb = 0, int tt = 0)
      : a(aa), b(bb), tp(tt) {}

    // void set_type(int t) { tp = t; }
protected:
    int a, b, tp
};

int main() {
    char t;
    int a, b;
    while (cin >> t >> a >> b) {
       foo f(a, b, t-'a');
    }
} 
gongzhitaao
  • 6,566
  • 3
  • 36
  • 44
0

I managed to fix my problem using the help from this link: thanks Scott Jones

Basically I created a special function whose whole purpose was to figure out which class it needs to create (A, B, C) and send it back for processing.

Base* Deserialize(std::ifstream &ifs)
{
 Base *temp;
 std::string what;
 ifs >> what;
 if (what== "A")
   {
      temp = new A();
      return temp;
   }
}

The reason this works is because this is a special function outside of both the base and the derived classes, it can see and use both of them.

Community
  • 1
  • 1
ptr0x01
  • 627
  • 2
  • 10
  • 25