[c++]Obiektowość - problem z funkcjami wirtualnymi

0

Mam takie oto klasy

class Field{
      public:
             virtual void Set(int x)=0;
             virtual void ShowAll()=0; 
             virtual int retPay()=0;   
};

class TownField:public Field{
      private:
              int price;
      public:
             void Set(int x);
             void ShowAll();
             void retPay(){};
};

class SpecialField:public Field{
      private:
              int x;
      public:
             void Set(int x);
             void ShowAll(){}
             void retPay();
};

Jak widać, w klasie SpecialField wcale nie jest wykorzystywana metoda ShowAll (od razu definiuję je jako puste) oraz w klasie TownField - metoda retPay. Teraz moje pytanie jest następujące. Czy da się jakoś tak zdefiniować funkcje ShowAll oraz retPay w klasie Field tak, żeby później nie było konieczne definiowanie tych funkcji w klasach dziedzicznych, które nie wykorzystują tych metod?
Z góry dziękuję za pomoc.
pozdrawiam

0

Wywal czysto abstrakcyjnosc z tych metod i zdefiniuj je normalnie w Field, pozostawiajac tylko jedna czysto abstrakcyjna.

0

To co chcesz zrobić to trochę brak logiki. Jeśli obiekty są "tego samego typu" oraz ten typ posiada pewną funkcjonalność to logiczne jest że obiekty klas pochodnych też te metody muszą mieć.
Od biedy możesz po prostu dać pustą definicję tych metod w Field (bo to w końcu C++ i dziedziczenie z klasy abstrakcyjnej, a nie implementacja Interfejsu) i napisać nowe definicje tylko w tych klasach gdzie chcesz, ale to nie jest dobre rozwiązanie.
Jak chcesz potem odróżniać czy dane pole jest takiego czy innego typu (bo skąd chcesz wiedzieć czy wywołanie danej metody ma sens?).

0

hmm, tylko że takie rozwiązanie nie działa w przypadku zmiennych dynamicznych. Mam tak:

class Field{
      public:
             void Set(int x){printf("funkcja wywolana w Field");};
             virtual void ShowAll()=0;
             int retPay(){};  
};

class TownField:public Field{
      private:
              int price;
      public:
             void Set(int x);
             void ShowAll();
};

...

int TownField::Set(int x){
      printf("funkcja wywolana w TownField");
}

..

Field *tab[40];
tab[0]=new TownField;
tab[0].Set(1); 

no i wyświetla się "funkcja wywolana w Field". Domyślam się że to dla tego, że wskaźniki są typu field. Jednak czy istnieje jakieś inne rozwiązanie(oprócz metod wirtualnych) tego problemu? Odpada takie coś:

TownField *tab;

gdyż dalej mam

tab[1]=new SpecialField;

Z gory dzięki za pomoc

0

Pics or it didn't happen. Wstawiasz tutaj kod z d**y który nie ma prawa sie skompilować i twierdzisz jeszcze bezczelnie że nie dość że sie kompiluje to jeszcze że działa nie tak jak powinien. Chamstwo i drobnomieszczaństwo...

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

class Field
{
public:
    virtual void Set(int x) //a to nie miało być virtual czasem?
    {
        printf("funkcja wywolana w Field");
    }
    virtual void ShowAll() = 0;
    int retPay() {return 0;};
};

class TownField: public Field
{
private:
    int price;
public:
    void Set(int x);
    void ShowAll(){}
};

void TownField::Set(int x) //a to nie miało być void?
{
    printf("funkcja wywolana w TownField");
}

int main()
{
    Field *tab[40];
    tab[0] = new TownField;
    tab[0]->Set(1); //metody ze wskaźnika wołamy za pomocą ->
    return 0;
}
0

Shalom, te klasy są rozbudowane, dla tego napisałem tylko fragmenty(ważne dla tematu). Nie patrzyłem w kod przez co zapomniałem strzałki. Teraz wszystko działa:) Dzięki wielkie

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