• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dziedziczenie, prywatna funkcja sortująca klasy pochodnej dla atrybutów klasy bazowej.

VPS Starter Arubacloud
0 głosów
567 wizyt
pytanie zadane 2 stycznia 2017 w C i C++ przez wanttobeanengineer Obywatel (1,120 p.)

Dzień dobry.

Mam pewien problem.
Otóż posiadając klasę A, której jednym z atrybutów jest tablica elementów typu double (public), tworzę klasę B, która jest pochodną klasy A. Klasa B poza elementami odziedziczonymi posiada tylko metodę sortującą (private). 
Klasa A natomiast posiada szereg metod i funkcji zaprzyjaźnionych (przeciążenia operatorów, alokowanie tablicy double, dodawanie elementu do tej tablicy, zmienianie rozmiaru itd.), które zmieniają długość/wartości tej tablicy. 
Klasa B ma być niemalże identyczna do A z tym wyjątkiem że ma przechowywać w tej tablicy elementy posortowane. Czyli przy każdym wywołaniu funkcji, która została napisana dla A i odziedziczone przez B, ma na bieżąco sortować tablicę z obiektu klasy B.

 

class A
{
public:
  double *t;
  int size;
  .
  .
  .
  void operator = (const A&);
  double& operaotr [](const int);
  void set_size(const int);
  void dodaj(const double);
  friend istream& operator >> (istream&, A&);
};

class B:public A
{
private:
  void sort();
  .
  .
  .
};

Przeładowanie operatora = nie zmienia jego zasady działania (tzn po prostu do jednego obiektu przypisuje drugi)
Przeładowanie operatora [] również nie zmienia (Obiekt[2] pozwala odnieść się do 3 elementu tablicy tej klasy)
funkcja set_size() ustawia nowy rozmiar, elementy tablicy nie są zamazywane a jeśli rozmiar jest większy od obecnego to dopisywane są zera
funkcja dodaj() dodaje element na końcu tablicy
operator >> również nie zmienia zasady działania, wczytuje po prostu do tablicy podane wartości

Moje pytanie jest takie:
Czy da się zrobić tak, aby klasa B dziedziczyła z A i posiadała tylko prywatną metode sort() oraz swoje konstruktory i destruktor, a mimo to po wywołaniu opisanych wyżej funkcji elementy w tablicy na bieżąco się sortowały?

Bo raczej nie chodzi o to, żeby przepisywać drugi raz te same metody skoro to jest dziedziczenie. 
Mogę to zrobić w taki sposób, że piszę definicje metody drugi raz dla klasy B i w niej zamiast pisać całego ciała tej metody to wywołuje odpowiadającą jej metodę klasy A a później funkcję sort(), ale takie rozwiązanie również chyba nie ma sensu.

Jak inaczej mogę to rozegrać aby przy każdym odniesieniu się do obiektu klasy B była wywoływana funkcja sort.
 

A Oa;
B Ob;

Ob = Oa;  // Od razu sortuje tablice która leci do Ob
Ob[3] = 5; // I sortowanie..
Ob.dodaj(); // Sortowanie..
Ob.set_size(5); // Sortowanie..

cin >> Ob; // I tu też sortuje..

 

2 odpowiedzi

0 głosów
odpowiedź 2 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

Sposobów jest kilka, między innymi te które już wymieniłeś.

Skoro chcesz, aby tutaj Ob = Oa; była wywoływana funkcja sort(), to w w ciele konstruktora kopiującego dopisz Sort(). Nie będzie to najprostsze rozwiązanie? I musisz także pamiętać o wywołaniu konstruktora przypisania w klasie pochodnej z referencją na klasę bazową, skoro kopiujesz obiekt klasy bazowej do obiektu klasy pochodnej.

komentarz 2 stycznia 2017 przez wanttobeanengineer Obywatel (1,120 p.)

Konstruktor jest, ale sort() nie mogę bezpośrednio w ciele metody klasy A bo obiekty klasy A nie mogą być sortowane. Natomiast pisanie drugi raz definicji metody dla klasy B trochę chyba przeczy założeniom obiektowości. 

komentarz 2 stycznia 2017 przez JAKUBW Nałogowiec (33,470 p.)
To zrób metodę abstrakcyjną i ją przysłoń w klasie B.
komentarz 2 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

Przecież sort() masz w klasie B. Ja to widzę tak:


class B : public A
{
private:
   void Sort();
   void operator=(const B & przypisanie);
}

B & B::operator=(const B & przypisanie)
{
   A::operator=(przypisanie); //kopiuje dane z klasy bazowej
   //tutaj przypisujesz tablicę obiektu A do tablicy obiektu B
   Sort(); //wywołuje metode Sort() klasy B sortującą tablicę
   return *this;
}

komentarz 2 stycznia 2017 przez wanttobeanengineer Obywatel (1,120 p.)

Evelek, tak właśnie zrobiłem, tylko chodzi o to, żeby własnie nie definiować drugi raz metod dla klasy B skoro je dziedziczę z A.
Bo te metody nie będą różnić się niczym, jedyna różnica w tym, że musi zostać tablica posortowana. I czy nie da się tego zrobić tak, żeby jakoś osobno, przy każdym odniesieniu do obiektu B wywoływać funkcję sort(), a nie wywoływać jej w powtórzonych definicjach metod.

komentarz 2 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
Nie rozumiem. Które metody się powtarzają w Twoim przykładzie?
komentarz 2 stycznia 2017 przez wanttobeanengineer Obywatel (1,120 p.)

Chociażby dodaj(), mam ją w klasie A, a później muszę napisać tą samą funkcję w klasie B.
Co prawda nie wykorzystuje tego kodu co w klasie A, bo w B::dodaj() zamiast całego ciała z A::dodaj() wywołuje najpierw A::dodaj() a później sort():
 

class A
{
public:
  void dodaj(double el)
  {
    //Cialo funkcji dodaj()
  }
};

class B: public A
{
private:
  void sort()
  {
    // Sortowanie
  }
public:
  void dodaj(double el)
  {
    A::dodaj(el);
    sort();
  }
};

 

komentarz 2 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

Skoro metoda void dodaj() klasy A jest publiczna, a klasa B dziedziczy publicznie po klasie A, to klasa B ma dostęp do metody void dodaj() klasy A. Możesz wywoływać tą metodę w klasie B. Jedyne na co musisz zwrócić uwagę, to aby jej użycie było poprawne - może ona działać poprawnie w klasie A, ale już niekoniecznie w klasie B.

class A
{
public:
	void dodaj(double el)
	{
		//Cialo funkcji dodaj()
	}
};

class B : public A
{
private:
	void sort(double el)
	{
		dodaj(el)
		//dalej ciało funkcji sortującej
	}
public:
};

Ja bym to tak zapisał, ale nadal nie jestem pewny czy o to Ci chodzi.

komentarz 2 stycznia 2017 przez wanttobeanengineer Obywatel (1,120 p.)

Nie o to..

Hmm..
 

class A
{
public:
  double *t;
  int size; // przechowuje faktyczna liczbe elementow w tablicy t
  A(){ //Konstruktor tworzy tablice liczb}
  void dodaj(double el)
  {
    t[size] =el;
    size++;
  }
}

class B: public A
{
  private:
    sort()
    {  // Tutaj tylko kod sortujacy tablice
    }
};


int main()
{ A a;
  // Niech a będzie obiektem klasy A z tablica liczb[0,1,2,3,4,5,6,7]
  B b;
  // Niech b będzie obiektem klasy B z taką samą tablicą liczb
  a.dodaj(3.5);
  b.dodaj(3.5);
   cout<<a; // Tu powinno wyświetlić tablicę [0,1,2,3,4,5,6,7,3.5]
   cout<<b; // A tutaj [0,1,2,3,3.5,4,5,6,7], czyli posortowaną
   // ALE UŻYWAJĄC JEDNEJ METODY, z tym że taką operacje przeprowadzić
   // żeby wykorzystać metodę sort() z klasy B już na tablicy
   // z dodanym elementem
}

Czyli funkcja dodaj() jest definiowana TYLKO w klasie A i z niej dziedziczona do klasy B.
Klasa B może ją wykorzystać bo to metoda publiczna, ale jeśli ją wykorzysta to po wstawieniu tego elementu na koniec, zostaje tablica z klasy B posortowana.

komentarz 2 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

Tworzysz dwa obiekty: jeden klasy A, drugi klasy B. Najpierw tworzymy pierwszy obiekt klasy A: A a(konstruktor klasy A);. Następnie tworzymy obiekt klasy B: B b(konstruktor klasy B);.

Chcesz następnie dodać jakąś liczbę do obiektu klasy A, wywołujesz metodę dodaj().

Następnie chcesz dodać tę samą liczbę do obiektu klasy B, wywołujesz metodę dodaj().

I nie wiem o co Ty chcesz dalej zrobić, w którym momencie w ogóle tablicę posortować, skoro nigdzie nie wywołujesz metody b.sort().

komentarz 2 stycznia 2017 przez wanttobeanengineer Obywatel (1,120 p.)

Już blisko jesteśmy :D
Właśnie o to pytam gdzie wywołać tą metodę sort()
b.sort() nie da się bo to metoda prywatna.
Wiec w jaki sposób to posortować. 
Bo zostaje mi tylko przeładować dodaj() na rzecz klasy B i w tym przeładowaniu sortować, ale np. mam też przeładowanie operator [] i tu już jest problem, bo nie mam pojęcia jak w tej funkcji posortować tablicę po umieszczeniu przez nią elementu pod indeksem.

komentarz 2 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

A czy funkcja sort() z klasy B musi być prywatna? Tak sobie wymyśliłeś, aby utrudnić? smiley Tylko czy to ma sens?

komentarz 3 stycznia 2017 przez wanttobeanengineer Obywatel (1,120 p.)
Musi być prywatna, ale nie ja to wymyśliłem tylko wykładowca.
0 głosów
odpowiedź 9 stycznia 2017 przez wanttobeanengineer Obywatel (1,120 p.)
edycja 10 stycznia 2017 przez wanttobeanengineer

Okej, o ile metody jakoś zrobiłem, to problemem jest dla mnie jak zrobić, żeby użycie operatora indeksowania sortowało tablicę w klasie B. 
Czyli, mam klasę A dla której robię przeładowanie operatora []. 
Ma również klasę B, która dziedziczy z klasy A.
Obie te klasy przechowują tablicę liczb typu double, ale w klasie B tablica ta zawsze ma być posortowana.
Czyli mając np. następujące liczby w obiekcie klasy B:
[0 1 4 7 8]
i zapisując:
 

main()
{
  double tab[] = {0,1,4,7,8};
  B objB(tab);
  B[2] = 9;
}

Powinno najpierw na miejscu 4 wstawić 9 -> [0,1,9,7,8]
a następnie posortować: [0,1,7,8,9]
Oczywiście metoda sortująca sort() jest prywatną metodą klasy B
Jakieś podpowiedzi?

Podobne pytania

0 głosów
5 odpowiedzi 1,874 wizyt
0 głosów
1 odpowiedź 661 wizyt
0 głosów
1 odpowiedź 220 wizyt
pytanie zadane 30 kwietnia 2021 w C# przez Adamek185wp Obywatel (1,280 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...