[C++] Dostęp do metody klasy pochodnej
Ostatnio zmodyfikowano 2013-08-18 00:52
pjpeg_objected Temat założony przez niniejszego użytkownika |
[C++] Dostęp do metody klasy pochodnej » 2013-08-17 12:04:10 Witam. Otóż borykam się z problemem dotyczącym dziedziczenia. Mam klasę base i derived. Chciałbym za pomocą wskaźnika typu base móc wywołać metodę typu derived. Czy jest to możliwe? Według mojego myślenia skoro mamy wskaźnik na typ derived to chociaż powinienem móc wywołać metodę publiczną tej klasy. Oto kod, który obrazuje mój problem: #include <iostream>
using namespace std;
class base { public: virtual void out() = 0; };
class derived : public base { public: derived( int a ) : x( a ) { } void out() { cout << x << endl; } void change( int x ) { this->x = x; } private: int x; };
int main() { base * p = new derived( 5 ); p->out(); p->change( 10 ); p->out(); delete p; return 0; }
|
|
tiger133 |
odp » 2013-08-17 13:40:57 class base { public: virtual void out() = 0; virtual void change( int a ) { } };
możesz tak napisać klasę base, ale nie jestem ekspertem. Więc możesz poczekać na odpowiedź jakiegoś bardziej doświadczonego programisty ; ) |
|
Matej |
» 2013-08-17 15:22:16 derived * d = new derived(); d = dynamic_cast < derived *>( p ); d->change( 10 );
Tzn nie jestem pewien czy dobrze ale ogólnie chodzi o to aby użyć rzutowania w dół. |
|
pjpeg_objected Temat założony przez niniejszego użytkownika |
» 2013-08-17 17:22:27 Hmm czyli jeżeli np trzymam w kontenerze std::map obiekty 3 różnych klas, które dziedziczą tą samą klasę, to jeżeli chce mieć dostęp do ich metod składowych muszę na początku zdefiniować 3 wskaźniki tych typów i rzutować w dół, czy muszę rzutować dopiero przed wywołaniem pożądanej funkcji? Dla ścisłości piszę menadżer obiektów i po prostu chciałbym stworzyć metodę, która podając w argumencie klucz, zwróci mi wskaźnik na określony obiekt żebym mógł z niego wywołać metodę niedziedziczoną. |
|
kampar |
» 2013-08-17 18:47:51 Kod, który podał Matej powinien wyglądać tak: derived * d = dynamic_cast < derived *>( p );
if( d != NULL ) d->change( 10 );
Co myślę jest odpowiedzią na twoje pytanie. Jeżeli masz taką możliwość (czyli poszczególne klasy pochodne mogą zawierać metody o takich samych nazwach, ale różnych definicjach) to najlepiej jest skorzystać z metod wirtualnych tak jak podał tiger133. Jeśli nie to musisz rzutować i możesz skorzystać z dynamic_cast, albo static_cast. Przy używaniu dynamic_cast nie musisz sprawdzać czy rzutujesz na właściwą klasę (jeśli rzutujesz źle to dynamic_cast zwraca NULL, co należy później sprawdzać przed wywołaniem metody). Niestety przez to jest dość wolny i nie zaleca się częstego używania. W przypadku static_cast przed rzutowaniem musisz sprawdzać, czy rzutujesz prawidłowo. Można to zrobić np. tak: class base { public: virtual int getType(); };
class derived : public base { public: int getType() { return 1; } };
class other : public base { public: int getType() { return 2; } };
int main() { base * p = new derived(); if( p->getType() == 1 ) { derived * d = static_cast < derived *>( p ); d->change(); } return 0; }
|
|
pjpeg_objected Temat założony przez niniejszego użytkownika |
» 2013-08-18 00:52:07 Dziękuje bardzo za odpowiedzi. Trochę poczytałem o rzutowaniu w dół i dowiedziałem się że w większości przypadków da się go uniknąć (przy dobrym zaprojektowaniu kodu) i myślałem że w tym przypadku też się da. No cóż muszę pomyśleć nad innym zarządzaniem obiektami. Jeszcze raz dzięki. Pozdrawiam. |
|
« 1 » |