Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Dostęp do metody klasy pochodnej

Ostatnio zmodyfikowano 2013-08-18 00:52
Autor Wiadomość
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:

C/C++
#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 ); //jak to wywolac?
   
    p->out();
   
    delete p;
   
    return 0;
}
P-90420
tiger133
odp
» 2013-08-17 13:40:57
C/C++
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 ; )
P-90427
Matej
» 2013-08-17 15:22:16
C/C++
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ół.
P-90441
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ą.
P-90451
kampar
» 2013-08-17 18:47:51
Kod, który podał Matej powinien wyglądać tak:
C/C++
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:
C/C++
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;
}
P-90454
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.
P-90463
« 1 »
  Strona 1 z 1