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

Dziedziczenie i rozszerzanie przeciążonych operatorów

Object Storage Arubacloud
0 głosów
329 wizyt
pytanie zadane 16 grudnia 2017 w C i C++ przez chacken Użytkownik (820 p.)

Mam następujący problem:
Klasa punkt z przeciążonym operatorem << do wypisywania współrzędnych punktu.
 

class Punkt{
    int x;
    int y;
public:
    Punkt(){
        x = 0;
        y = 0;
    }
    ~Punkt(){
    }
    friend ostream &operator<<( ostream &output, const Punkt &D );
};

ostream &operator<<(ostream &output, const Punkt &D) {
    output << "(" << D.x << "," << D.y << ")" << endl;
    return output;
}

Klasa Dziedzicząca po tej klasie posiada również operator << nadpisując operator klasy rodzica ALE wypisujac dane ma skorzystać z istniejącego już operatora rodzica i dopisać coś swojego.

 

class Okrag : public Punkt {
    int promien;
public:
    Okrag(){
        promien = 1;
    }
    friend ostream &operator<<( ostream &output, const Okrag &D );
};

ostream &operator<<(ostream &output, const Okrag &D) {
    output << "Okrag [Promien: " << D.promien << ", Srodek(" // cos tutaj co wypisze punkt rodzica korzystajac z operatora
    return output;
}

Problem jest taki ze nie mam pojecia jak zrobic to tak zeby w operatorze klasy dziecka (Okrag) wykorzystac jakos operator rodzica tak zeby w wypisywanej calosci pojawil sie tekst dodany w okregu + tekst rodzica

Odrazu mowie ze nie moge zrobic zmiennych protected, nie moze korzystaz z getterow setterow. Mam wykorzystac jakos operator rodzica w operatorze dziecka wypisujac dane i nowe z dziecka i juz istniejace z rodzica. 
Nie mam pojecia internet przeszukany ;/
Jakies rady?

1 odpowiedź

+3 głosów
odpowiedź 16 grudnia 2017 przez mokrowski Mędrzec (155,460 p.)
wybrane 18 grudnia 2017 przez chacken
 
Najlepsza

Nie wiem jakie masz ograniczenia co do rozwiązania samego zadania. Szczególnie jeśli zostało Ci zlecone. Więc traktuj uwagi jako uwagi do kodu który pojawiał by się w ew. projekcie.

  1. Dziedziczenie Punkt -> Okrąg jest średnim pomysłem. Ci wspólnego ma pojęcie punktu z pojęciem okręgu? Raczej jest tak że obiekt okrąg, posiada czyli agreguje lub wkomponowuje punkt. Agreguje jeśli nie będzie odpowiedzialny za jego zniszczenie a wkomponowuje jeśli w trakcie destrukcji obiektu typu Okrąg, zniszczy także obiekt typu Punkt. W konsekwencji, nie ma sensu tworzyć obiektu Okrąg bez... środka! Można więc mu ten środek podać w konstruktorze.
  2. Aby uniknąć niechcianych konwersji Okrag <- Punkt, konstruktor z argumentem środka, należy uczynić explicit. 
  3. Jeśli można, warto unikać relacji friend. To dehermetyzacja obiektu z utratą kontroli kto z czego korzysta. Lepszym rozwiązaniem jest tworzenie dedykowanej metody dostępu do danych. W rozwiązaniu z friend, wystarczy że nazwę funkcję tak jak w deklaracji przyjaźni i już dostaję się do wszystkich elementów prywatnych klasy. W rozwiązaniu z dedykowaną funkcją. masz pełną kontrolę.
  4. Można rozważyć tworzenie punktu bez podawania współrzędnych. Wtedy będzie posiadał współrzędne 0, 0. 
  5. Należy preferować inicjalizację atrybutów w ramach listy inicjalizacyjnej. Unikniesz w ten sposób dwukrotnego tworzeniu obiektu. Jeden raz przez domyślny konstruktor przed wejściem do ciała konstruktora, drugi raz w trakcie inicjowania w jego ciele.
  6. Funkcje które nie dokonują zmian w obiekcie, powinny mieć atrybut const. Tak aby chronić przed pomyłkowymi zmianami na przyszłość.
  7. Jeśli przyjmujesz konwencję nazywania klasy w stylu CamelCase, nazwy atrybutów i metod rozpoczynają się wtedy od małej litery. Wiem że to raczej konwencja, ale warto się jej trzymać.
  8. Nie używaj using namespace std; , Używaj pełnego dostępu kwalifikowanego.

Oczywiście brakuje jeszcze innych metod w Okrag i Punkt. Tu jednak nie wiem jakie mają być zastosowania.

Najważniejszym argumentem za tym aby nie stosować (bez potrzeby) rzutowania na wskaźnik w ramach drzewa dziedziczenia, jest łamanie reguły Zasady Podstawienia Liskov https://pl.wikipedia.org/wiki/Zasada_podstawienia_Liskov . Rzutowanie jest objawem łamania tej reguły. 

Oczywiście "jeśli Ci kazali", nie mam pytań. Wiedz jednak że dobra praktyka jest bliżej tego co opisałem.

Ja bym zrobił to tak:

#include <iostream>

class Punkt{
public:
    Punkt(int x_ = 0, int y_ = 0): x(x_), y(y_) {
    }
    ~Punkt(){
    }
    std::ostream& reprezentacja(std::ostream &output) const {
        output << "(" << x << "," << y << ")";
        return output;
    }
private:
    int x;
    int y;
};
 
std::ostream &operator<<(std::ostream &output, const Punkt &d) {
    return d.reprezentacja(output);
}

class Okrag {
public:
    explicit Okrag(const Punkt& p_): srodek(p_), promien(1) {
    }
    std::ostream& reprezentacja(std::ostream &output) const {
       output << "Okrag: [Promien: " << promien << ", Srodek";
       srodek.reprezentacja(output);
       output << ']';
       return output;
    }
private:
    int promien;
    Punkt srodek;
};
 
std::ostream &operator<<(std::ostream &output, const Okrag &d) {
    d.reprezentacja(output);
    return output;
}

int main() {
    Punkt p(10, 20);
    Okrag o(p);
    std::cout << o << std::endl;
}

 

Podobne pytania

0 głosów
0 odpowiedzi 337 wizyt
pytanie zadane 27 listopada 2016 w C i C++ przez rc000 Nowicjusz (120 p.)
0 głosów
2 odpowiedzi 172 wizyt
0 głosów
3 odpowiedzi 954 wizyt

92,572 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...