operatory wczytania a dziedziczenie

0

Witam, otóż mam mały problem, mianowicie mam klasę bazową, i dziedziczącą po niej klasę pochodną, i teraz muszę zrobić odczyt danych z plików tak, by mi zapisało również dane do klasy pochodnej.

już pokazuje, o co chodzi mi dokładniej:

class bazowa
{
	public:
	int a;
	bazowa(){};
        bazowa *nast;
	friend istream& operator>>(istream&, bazowa&);
}

class pochodna:public bazowa
{
	public:
	int b;
	pochodna():bazowa(){};
	
}

istream& operator>>(istream& ist, bazowa& baz)
{
	ist>>baz.a;
	ist>>baz.b;
	return ist;
}

int main()
{
	bazowa *wsk;
	ifstream plik;
	plik.open("test.txt");
	wsk=new pochodna();
	plik>>*wsk;
}

a to plik test.txt

1 5
2 6

Generalnie w istream, ist>>baz.b; nie chce się zrobić, gdyż (jak widać gołym okiem) klasa bazowa nie posiada atrybutu 'b'.
Tworzenie obiektu musi tak wyglądać, ponieważ później będzie więcej klas pochodnych, i będzie to lista(wsk=new pochodna(); wsk->nast=new pochodna2(); wsk=wsk->nast; itd). Może być parę pochodnych, ale one mają tworzyć właśnie listę(w ten sposób wcześniej na ćwiczeniach robiliśmy listy obiektowe, ale nie robiliśmy właśnie stream'a na klasy dziedziczące, tylko na bazowe).

Pozdrawiam, i z góry dzięki za odpowiedź.

0

Zrób sobie wirtualną metodę do wczytywania ze strumienia i jej używaj wewnątrz operatora.

#include <iostream>
 
class Base {
public:
  int a;
 
  virtual void load(std::istream &s) {
    std::cout << "Base::load" << '\n';
    s >> a;
  }
};
 
class Derived : public Base {
public:
  int b;
 
  virtual void load(std::istream &s) {
    std::cout << "Derived::load" << '\n';
    Base::load(s);
    s >> b;
  }
};
 
std::istream &operator>>(std::istream& s, Base &b) {
  std::cout << "operator>>" << '\n';
  b.load(s);
  return s;
}
 
int main() {
 
  Derived d;
 
  std::cin >> d;
 
  std::cout << d.a << ' ' << d.b << '\n';
        
  return 0;
}

http://ideone.com/ODDsU

0

dzięki wielkie:)

1

A jeżeli chcesz automatyczne rozpoznanie co siedzi w strumieniu i jaką klasę należy stworzyć to coś takiego musisz opracować:

#include <iostream>
#include <iomanip>
#include <sstream>
#include <typeinfo>
using namespace std;

class Base
  {
   public:
   virtual ~Base() {}
   virtual ostream &save(ostream &s)const { return s; }
   virtual istream &load(istream &s) { return s; }
   virtual void Who()const {}
   virtual bool ItsMe(const type_info &t)const { return false; }
   virtual Base *create()const { return 0; }
   static const Base *RegTb[];
   static const unsigned RegTbSize;
   unsigned Id();
  };
ostream &operator<<(ostream &s,const Base &B) { return B.save(s); }
istream &operator>>(istream &s,Base &B) { return B.load(s); }

template<class base> class regbase:public Base
  {
   public:
   virtual Base *create()const;
   virtual bool ItsMe(const type_info &t)const { return t==typeid(base); }
  };

template<class base> Base *regbase<base>::create()const 
  {
   return new base();
  }

unsigned Base::Id()
  {
   const type_info &t=typeid(*this);
   for(unsigned i=0;i<RegTbSize;++i)
     {
      if(RegTb[i]->ItsMe(t)) return i;
     }
   throw Base();
  }

struct Int:public Base
  {
   virtual void Who()const { cout<<"Int"<<endl; }
  };

struct Double:public Base
  {
   virtual void Who()const { cout<<"Double"<<endl; }
  };

struct String:public Base
  {
   virtual void Who()const { cout<<"String"<<endl; }
  };

const Base *Base::RegTb[]= // tabela z "zarejestrowanymi" klasami
  {
   new regbase<Int>(),
   new regbase<Double>(),
   new regbase<String>(),
  };
const unsigned Base::RegTbSize=sizeof(Base::RegTb)/sizeof(*Base::RegTb);

int main()
  {
   Base *Tb[]={new Int(),new Double(),new String()};
   unsigned TbSize=sizeof(Tb)/sizeof(*Tb);
   stringstream s;
   for(unsigned i=0;i<TbSize;++i)
     {
      s<<Tb[i]->Id()<<' '<<(*(Tb[i])); // zapis do strumienia wraz z Id
     }
   for(unsigned i=0;i<TbSize;++i) Tb[i]->Who(); // wypisujemy dane
   cout<<endl;

   s.seekg(0,ios::beg);
   Base *Tc[TbSize];
   for(unsigned i=0;i<TbSize;++i)
     {
      unsigned id;
      s>>id;  // odczyt id ze strumienia
      Tc[i]=Base::RegTb[id]->create(); // utworzenie odpowiedniego obiektu
      s>>(*Tc[i]); // odczyt danych ze strumienia
     }
   for(unsigned i=0;i<TbSize;++i) Tc[i]->Who(); // wypisujemy odtworzone dane

   cin.sync();
   cin.get();
   return 0;
  }
0

huh, ale to zawiłe przyznam;p ale dzięki^^ choć z tym poradziłem sobie w ten sposób, że wczytuje pierwszy bit, i na jego podstawie tworze odpowiednie obiekty, i tak z każdą nową linijką :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1