Przesłanianie zmiennych w klasach oraz trzymanie klas dziedziczonych w tablicach wskaźników
Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Zarejestruj się!

Przesłanianie zmiennych w klasach oraz trzymanie klas dziedziczonych w tablicach wskaźników

AutorWiadomość
Temat założony przez niniejszego użytkownika
Przesłanianie zmiennych w klasach oraz trzymanie klas dziedziczonych w tablicach wskaźników
» 2018-07-09 13:00:07
Cześć. Nie wiem czy dobrze napisałem tytuł tematu, ale to raczej średnio ważne. Załóżmy, że mam dwie klasy:
C/C++
class A
{
public:
    int pole = 1;
    void metoda();
};

class B
    : public A
{
public:
    int pole = 5;
    void innaMetoda();
};
Oraz tablicę typu A*, w której będę trzymał B* (oraz A*):
C/C++
A * w_tab[ 10 ];
for( int i = 0; i < 10; i++ )
{
    w_tab[ i ] = new A();
}
w_tab[ 2 ] = new B();
To dlaczego, jak chcę uzyskać dostęp do pola
w_tab[ 2 ]->pole
 otrzymuję 1? Oraz czemu nie mogę użyć metody
w_tab[ 2 ]->innaMetoda()
?

Mam nadzieję, że niczego tu nie pomotałem...
P-171792
» 2018-07-09 14:36:01
Zacznijmy od tego, że ten przykład nie jest najlepszy i dla niego dziedziczenie nie ma żadnego sensu.
1. Pola klasy powinny być
private
 lub
protected
.
2. Brakuje
virtual
 destruktora.

To dlaczego, jak chcę uzyskać dostęp do pola
w_tab[ 2 ]->pole
 otrzymuję 1?
Bo masz zadeklarowane
A * w_tab[ 10 ];
 i zawsze odwołujesz się do pól klasy bazowej.

Oraz czemu nie mogę użyć metody
w_tab[ 2 ]->innaMetoda() ?
.
To samo co wyżej. Ta metoda należy do klasy
B
, a wywołujesz obiekt klasy
A
.

#include <iostream>

class A {
public:
   int field;
   A() : field{ 1 } {}
   virtual ~A() {}
   virtual void method() const { std::cout << __FUNCTION__ << std::endl; }
};

class B : public A {
public:
   int field;
   B() : field{ 2 } {}
   virtual ~B() {}
   virtual void method() const { std::cout << __FUNCTION__ << std::endl; }
};

int main() {
   A* p[2];
   p[0] = new A();
   p[1] = new B();
   for (int i = 0; i < 2; ++i) {
      std::cout << p[i]->field << ": " << std::endl;
      p[i]->method();
   }
   for (int i = 0; i < 2; ++i) {
      delete p[i];
   }
   return 0;
}

» Kurs C++ » Poziom 5Wskaźniki inteligentne (C++11) lekcja zamiast gołych
new
 i
delete
.
P-171793
Temat założony przez niniejszego użytkownika
» 2018-07-09 19:10:40
Zacznijmy od tego, że ten przykład nie jest najlepszy i dla niego dziedziczenie nie ma żadnego sensu.
1. Pola klasy powinny być private lub protected [...]
Wiem. Po prostu chciałem się dowiedzieć, czemu tak się dzieje. Nie chciałem się zbyt rozpisywać, ani kopiować sporej (~200 linijek) ilości kodu z projektu, w którym spotkałem się z tym problemem.
Bo masz zadeklarowane
A * w_tab[ 10 ];
i zawsze odwołujesz się do pól klasy bazowej.
Okej... Czyli w tym przypadku wcale nie mogę używać metod klasy dziedziczącej?
C/C++
B()
    : field
{ 2 } { }
Nie rozumiem tego zapisu. Wyjaśnisz?
P-171807
» 2018-07-09 19:19:30
To dlaczego, jak chcę uzyskać dostęp do pola
w_tab[ 2 ]->pole
 otrzymuję 1?
Nie ma czegoś takiego jak "wirtualne zmienne" w klasie. Są wirtualne metody, które robią to, czego oczekujesz. Na zwykłych danych w klasie nie możesz tego zrobić.

Oraz czemu nie mogę użyć metody
w_tab[ 2 ]->innaMetoda() ?
Wskaźnik jest typu A, więc możesz używać wyłącznie rzeczy zdefiniowanych w A. Jak chcesz się dostać do elementów klasy pochodnej, musisz rzutować wskaźnik, np przez dynamic_cast<>.

C/C++
B()
    : field
{ 2 } { }
Nie rozumiem tego zapisu. Wyjaśnisz?
To samo co
C/C++
B()
    : field( 2 )
{ }
P-171808
Temat założony przez niniejszego użytkownika
» 2018-07-10 14:11:23
Dzięki. Problem rozwiązany. Zamykam.
P-171810
« 1 »
 Strona 1 z 1