deklaracja klasy zapowiadajacej i dziedziczenie

0

Witam,
oto kod:

 
class Ram{...}
class RamLaptop:public Ram{...}
class FK;

class FL:public FK{
public:
Ram*createram(){
return new RamLaptop;
}
};

class FK{
public:
    FL*fl;
    FK*fk;
    FK*dajfabryke(string n){
    if(n=="laptop")
    return fl;
   }
   virtual Ram* createram(){};
   FK();
}; 

problem w tym, że raczej nie można dziedziczyć po niezdefiniowanej klasie, która jest jedynie zapowiedziana, w każdym razie występuje taki błąd:
"invalid use of incomplete type 'class FK' "
Próbowałem zamienić kolejność, ale wtedy pojawia się błąd konwersji wskażnika fl typu FL do typu FK we fragmencie:

  FL*fl;
  FK*fk;
  FK*dajfabryke(string n){
   if(n=="laptop")
    return fl;
   }

Czy ktoś ma jakiś pomysł jak rozwiązać ten problem?

4
  1. Nie możesz dziedziczyć po klasie niekompletnej
  2. Jeśli już robisz takie rzeczy to MUSISZ oddzielić implementacje od deklaracji. Tzn ciała metod lecą do pliku *.cpp a w plikach *.h zostaja tylko deklaracje klas.
4

Nie można dziedziczyć po niekompletnej klasie, za to można zadeklarować wskaźnik niekompletnego typu. Więc rozwiązaniem problemu kompilacji jest coś takiego:

class FL;

class FK {
public:
    FL* fl;
    FK* fk;
    FK* dajfabryke(string n);
    virtual Ram* createram(){};
    FK();
};

class FL : public FK {
public:
    Ram* createram()
    {
        return new RamLaptop;
    }
};

FK* FK::dajfabryke(string n)
{
    if (n == "laptop")
        return fl;
}

Natomiast cały ten cyrk wynika z tego, że trzymasz wskaźnik do klasy pochodnej w klasie bazowej. Pytanie czy to jest konieczne. Na obiekt klasy pochodnej może wskazywać wskaźnik klasy bazowej, o czym mam nadzieję wiesz.

0
class Ram{...}
class RamLaptop:public Ram{...}
class FL;
  
class FK{
public:
    FL*fl;
    FK*fk;
    FK*dajfabryke(string n){
     if(n=="laptop")
     return fl;
   }
   virtual Ram* createram() {};
   FK();
}; 

class FL : public FK{
public:
Ram*createram(){
 return new RamLaptop;
}
};

Powinno działać. Wskaźniki klas niekompletnych da się tworzyć. Obiekty i dziedziczenie już nie.

0

Dziękuję za szybkie odpowiedzi, powyższy problem rozwiązany, jednak pojawił się inny, funkcja dajfabryke() powinna zwracać obiekt, aby go można użyć do wywołania funkcji createram() zamiast odwoływać się do konkretnej klasy przy jego tworzeniu. Czy rozwiązaniem mogłobybyć użycie składni:

 
void Ram::show(){
    cout<<"Ram dla laptopa"<<endl;
    };

int main()
{  
    FK*fk=new (tutaj funkcja określająca typ zwróconego wskażnika)fk->dajfabryke("laptop");
    Ram*ram=fk->createram();
    ram->show();
    return 0;
}
 

Nigdzie nie mogę znależć funkcji określającej typ, a kiedyś o niej czytałem. Czy może jest bardziej eleganckie rozwiązanie?

@mwl4 no właśnie pojawia się błąd konwersji wskażnika fl typu FL do typu FK

0

Problem rozwiązany:)

FK* FK::dajfabryke(string n)
{
    if (n == "laptop")
        return new FL;
}
int main()
{
    FK*fl=fl->dajfabryke("laptop");
    Ram*ram=fl->createram();
    ram->show();
    return 0;
} 
0

A potem masz wyciek pamięci, bo nic nie sprząta tych obiektów tworzonych przez

return new FL
0

@twonek delete fl;
oczywiście wiem, że należy sprzątać po wskażnikach utworzonych przy pomocy operatora "new" to jest tylko program do przećwiczenia wzorca fabryka abstrakcyjna, ale dziękuję za rade.
Jeszcze tylko jedno pytanie, zadeklarowałem klasy w osobnym pliku nagłówkowym *.h, ale pojawia się błąd :

class FL;
class FK{
public:
   FK*dajfabryke(string n);    //tutaj error: expected ';' at end of member declaration|
   virtual Ram* createram(){};
}; 

kompletnie nie wiem o co chodzi, przy deklaracji w pliku *.cpp jest ok.

1
jarmac napisał(a):

@twonek delete fl;
Nadal będzie wyciek, bo FK nie ma wirtualnego destruktora.

Jeszcze tylko jedno pytanie, zadeklarowałem klasy w osobnym pliku nagłówkowym .h, ale pojawia się błąd
A masz #include <string>? Jeśli tak to użyj pełnej nazwy std::string.

0

@twonek dzięki wielkie, faktycznie pomogło

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