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

question-closed C++, dziedziczenie. Problem związany ze wskaźnikiem klasy bazowej na klasę pochodną.

Object Storage Arubacloud
0 głosów
671 wizyt
pytanie zadane 1 czerwca 2018 w C i C++ przez Jakub 0 Pasjonat (23,120 p.)
zamknięte 1 czerwca 2018 przez Jakub 0

Witam, myślałem że tym razem obejdzie się bez większych problemów ale C++ znowu stawia mi figle których ja nie potrafię zrozumieć ;( Mam taki banalny przykład dziedziczenia:

class A {
	int a;
public:
	A(int v) : a(v) {}

	int& returna() {
		return a;
	}
};

class B : public A {
	int b;
public:
	B(int v1, int v2) : A(v1), b(v2) {}

	int& returnb() {
		return b;
	}
};

I takie dynamiczne przydzielenie:

A* aaa = new B(1,2);

Odwołanie się:

aaa->returna();

Jest poprawne, ale:

aaa->returnb();

Powoduje błąd kompilacji że klasa 'A' nie posiada takiej metody. Ale zaraz, przecież wskaźnik klasy 'A' wskazuje na dynamicznie przydzielony obiekt pamięci klasy 'B'.

B bbb(2, 2);
A* aaa = &bbb;
aaa->returna();
aaa->returnb(); //to też powoduje błąd 

Czy naprawdę nie da się odwołać do składowej klasy pochodnej za pomocą wskaźnika lub referencji typu klasy bazowej? Jeśli tak, a problem nie wynika z mojego niedopatrzenia to mega słabo :/ ( dziedziczenie traci trochę sensu w moich oczach )

* wiem oczywiście o metodach wirtualnych, ale to tylko inna postać metody o takiej samej nazwie w klasie pochodnej.

komentarz zamknięcia: już znam wytłumaczenie

1 odpowiedź

0 głosów
odpowiedź 1 czerwca 2018 przez criss Mędrzec (172,590 p.)
wybrane 1 czerwca 2018 przez Jakub 0
 
Najlepsza
Wszystko jest ok - tak ma być. Dziedziczenie działa w strone od bazowej do pochodnej (jak nazwa wskazuje :D) tzn B dziedziczy elementy A, nie odwrotnie.
komentarz 1 czerwca 2018 przez Jakub 0 Pasjonat (23,120 p.)

To niezbyt fajnie bo widziałem zastosowanie dla czegoś takiego... Ale C++ zmienić nie potrafię ( i tak ma za dużo możliwości jak na moją głowę i to trzeba cenić laugh ). Mam tylko jedno dodatkowe pytanie dotyczące destruktorów wirtualnych:

A* aaa = new B(1,2);
delete aaa; // zwolnienie pamięci 

Skoro dla obiektu klasy 'B' wykona się destruktor tylko klasy 'A' ( bo nie jest on wirtualny i ma jedną postać - postać dla typu referencji lub wskaźnika ). To obiekt nie zostanie zwolniony w całości? Tzn. czy zwolniony zostanie tylko pod obiekt odziedziczony z klasy 'A'?

komentarz 1 czerwca 2018 przez criss Mędrzec (172,590 p.)

Tak, dokładnie, dlatego najlepiej zawsze tworzyć wirtualny destruktor jeśli dana klasa ma być bazową.

komentarz 1 czerwca 2018 przez Jakub 0 Pasjonat (23,120 p.)
Dziękuje, to wszystko
1
komentarz 1 czerwca 2018 przez criss Mędrzec (172,590 p.)
Ah chwileczka, chyba nie do końca dobrze zrozumiałem Twoje pytanie. Obiekt zostanie zwolniony cały (tzn. pamięć w której "mieszkał", tak mi się wydaje przynajmniej.. nie widze powodu dla którego miałoby tak nie być bo to ten sam blok pamięci, ale nie jestem 100% pewien), ale nie zostanie uruchomiony destruktor B. Więc jeśli w destruktorze B dzieje się coś ważnego (zamykanie pliku, zwalnianie innej pamięci...), to to się nie stanie dopóki destruktor A nie będzie virtual lub wskaźnik `aaa` nie będzie typu B*.
komentarz 2 czerwca 2018 przez Jakub 0 Pasjonat (23,120 p.)

W mojej książce ( C++, Szkoła Programowania ) :

 

Pisze tu oczywiście o przypadku jeżeli w klasie pochodnej obsługujemy pamięć dynamiczną. Jednak jest tu wzmianka że wywołanie delete ( bez destruktora wirtualnego ) zwolni z pamięci składowe klasy bazowej, "ale już nie pamięci zajmowanej przez nowe składowe tak klasy ( pochodnej )". Pisze tu ogólne składowe a nie tylko o pamięci na którą wskazuje wskaźnik char*. Tak jak by część zawartości klasy pochodnej tkwiła potem w pamięci. No chyba że nie przeczytałem tego ze zrozumieniem :/

komentarz 2 czerwca 2018 przez monika90 Pasjonat (22,940 p.)
Bez znajomości szczegółów konkretnej implementacji C++ nie wiadomo co się stanie, bo zachowanie jest niezdefiniowane.

Podobne pytania

0 głosów
2 odpowiedzi 805 wizyt

92,541 zapytań

141,383 odpowiedzi

319,482 komentarzy

61,929 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!

...