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

Przesłanianie się metod

Ostatnio zmodyfikowano 2011-08-29 10:04
Autor Wiadomość
wizardus
Temat założony przez niniejszego użytkownika
Przesłanianie się metod
» 2011-08-11 13:09:09
Witam, mam pytanie. Czy jest możliwe że gdy mam takie oto klasy:

C/C++
class PPodstawowa
{
private:
    /*
    Nieistotne
    */
   
public:
   
    virtual void metoda();
};

class CDziedziczyzPodstawowej
    : public PPodstawowa
{
private:
    /*
    Nieistotne
    */
   
public:
    virtual void metoda();
   
}

class CDziedziczyZPochodnej
    : public CDziedziczyzPodstawowej;
{
private:
    /*
    Nieistotne
    */
   
public:
    void metoda();
   
}

class CDrugaCoDziedziczyzPodstawowej
    : public PPodstawowa
{
private:
    /*
    Nieistotne
    */
   
public:
    void metoda();
   
}

To CDziedziczyZPochodnej::metoda() moze przeslonic CDrugaCoDziedziczyzPodstawowej::metoda() ?

nie są nawet na jednym poziomie drzewa ... a mimo wszystko wygląda to właśnie jakby jedna metoda przesłaniała drugą.
P-38759
SeaMonster131
» 2011-08-11 13:12:52
Weź to ogarnij jakoś..
P-38760
DejaVu
» 2011-08-11 14:27:40
No bo metody o tej nazwie się 'przesłaniają'. Poczytaj o metodach wirtualnych itp. Lepiej napisz co chcesz uzyskać - będzie łatwiej dojść do celu :)
P-38766
Mrowqa
» 2011-08-11 15:10:23
Po pierwsze - w klasie podstawowej wystarczy
virtual
 - każde następne metody o tej nazwie w klasach pochodnych będą przez  domniemanie wirtualne.
Tak - nazwy się zasłaniają. Do zwykłych zasłoniętych składników danych i metod (nie jestem pewien czy wirtualnych też, ale myślę, że tak) wolno się odnieść za pomocą specyfikatora zakresu ::, np.
C/C++
class a
{
public:
    int skl; // obojetne czy metoda, czy zmienna, liczy sie nazwa
};
//----------------------
class b
    : public a
{
public:
    void skl( void ) { }
};
//----------------------
b obj;
b.skl(); // wywolanie funkcji skladowej z klasy b
//b.b::skl();
b.a::skl = 3; // przypisanie do zaslonietej zmiennej ;)
O to chodziło ?? ;)
P-38774
wizardus
Temat założony przez niniejszego użytkownika
» 2011-08-11 21:17:59
Mamy zalozmy 4 klasy :)

Babcia, Tata, Wujek, Dzieciak

Klasa babcia ma metode x która to jest virtual void x();

No i Tata ma swoją implementacje tej metody, Wujek swoją, Dzieciak swoją :)

Problem w tym że gdy najpierw wywołam metodę wujka, a potem dzieciaka, to ponowne wywołanie metody wujka skutkuje wywołaniem metody dzieciaka:) To tak bardziej obazowo :]

Mrówqa thx :] mniej więcej o to chodziło, tylko teraz mam np tablice 5 przycisków o tak o:

C/C++
PButton * m_pButton[ 5 ];

z tym że każdy m_pButton to obiekt innego typu np:

C/C++
m_pButton[ 0 ] = new CMenuButton;
m_pButton[ 1 ] = new CContentButton;
m_pButton[ 2 ] = new CQuitButton;

etc.etc.etc.

No i zakładając że mam metodę

C/C++
void CheckMouseClick();

dla każdego takiego przycisku to mógłbym puścić to w pętli:

C/C++
for( int i = 0; i < 5; i++ )
{
    m_pButton[ i ]->CheckIfClick();
}

teraz każdy przycisk ma jeszcze metode:

C/C++
void OnClick();

i swoją własną implementacje (dziedziczą tylko nazwe od przycisku rodzica gdzie metoda jest wirtualna).

Wtedy przykladowa funkcja CheckIfClick() wygląda tak:
C/C++
void CheckIfClick()
{
    if( m_bIsActive )
    {
        this->OnClick();
    }
}

No i tu jest problem.

Mam dwa przyciski i tak, najpierw wciskam pierwszy, wywoluje sie jego metoda, potem drugi, wywoluje sie jego OnClick, a jak znowu wcisnę pierwszy to wywołuje mi sie OnClick drugiego.

Mogę zrobić np sprawdzanie typu obiektu ewentualnie, albo pozmieniac nazwy. Jakies inne, lepsze rozwiazania żeby kod był bardziej "wszechstronny" ?

P-38902
Mrowqa
» 2011-08-12 14:43:28
Co do tych metod, to niezbyt rozumiem... W jakiej bibliotece piszesz? Więcej kodu? ;P
Mogę zrobić np sprawdzanie typu obiektu(...)?
Dla dziedziczenia został stworzony specjalny operator -
dynamic_cast
.
C/C++
/* zalozmy ze mamy trzy klasy:
a,
b : public a,
c : public a.
*/
a objA, * wskA;
b objB, * wskB;
c objC, * wskC;
wskA = & objA; // mozna
wskA = & objB; // dzieki polimorfizmowi mozliwe ;)
wskC = wskA; // !!! kompilator nie pozwoli !!! konwersja jest: poch -> podst, nie odwrotnie!
wskC = dynamic_cast < c * >( wskA );
dynamic_cast działa tak, że sprawdza, co się kryje pod konkretnym wskaźnikiem i jeśli typ się zgadza - zwraca adres obiektu, a jeśli typ się nie zgadza - zwraca NULLa ;P

Jest także druga, nie zalecana technika zwana RTTI (run-time type identification):
C/C++
#include <typename.h> // u mnie akurat nie trzeba zalaczyc w visualu ;)
//...
int a = 4;
cout << "zmienna \"a\" jest typu: " << typeid( a ).name(); // wypisze "int" ;)
//wolno także tak:
obj * cos;
// nadajemy wartosc
if( typeid( * cos ) == typeid( int ) ) cout << "Hurra! \"cos\" wskazuje na liczbe typu int!";

Jednak ta technika nie jest zalecana, choć czasem się przydaje ;)
P-38964
wizardus
Temat założony przez niniejszego użytkownika
» 2011-08-12 14:51:46
Myślałem że dynamic_cast i RTTI to to samo tzn że wiąże się jakoś ze sobą.

Piszę w SDL'u, czytałem po forach i podobno jest lepszy od SFML pod względem mobilności.

Chodzi o to że mam dwa przyciski. Klikam pierwszy->Wykonuje sie jego metoda (1), Klikam drugi->Wykonuje sie metoda (2), Klikam pierwszy-> Wywołuje się metoda (2).

Muszę jeszcze dokładnie sprawdzić kod bo może gdzieś coś sie nadpisuje a ja o tym nie wiem O.o ...

Trzeci dzień kombinuje.
P-38965
Mrowqa
» 2011-08-12 15:11:42
Problem w tym, że po Twoich opisach dużo się nie dowiem :P Kod może by pomógł...

A co do dynamic_cast i RTTI... RTTI jak sama nazwa wskazuje - run-time type identification, czyli rozpoznanie typu podczas wykonywania programu, a dynamic_cast tak właśnie robi ;) Tyle, że podałem też inną metodę.
P-38968
« 1 » 2
  Strona 1 z 2 Następna strona