Serwis został przeniesiony pod nową domenę: http://cpp0x.pl/
PowrótPowrótHistoria odwiedzonych stron
AutorWiadomość
Data: 2007-12-14 23:48:46

world007
Dziedziczenie wielokrotne

Mam otóż taki problem.
jest funkcja:

#include <iostream.h>
class A{
  public:
  int a;
};
class C : public A{
  public:
  int c;
};
class B : public A{
  public:
  int b;
};
class D : public B, public C{
  public:
  int d;
};
int main()
{
  D Obiekt;
  cout << "Skladowa a od klasy B: " << Obiekt.B::a << endl;
  cout << "Skladowa a od klasy C: " << Obiekt.C::a << endl;

  return 0;
}



B i C dziedziczą po A, a D dziedziczy po B i C.
I takie odwołania: Obiekt.B::a i Obiekt.C::a,
niby tyczą się tej samej zmiennej a, jednak
wyświetlane są inne wyniki, tak jakby kompilator robił 2 kopie zmiennej a, które są dostępne z klasy D (jak by istniały dwie zmienne a)

Moje pytanie brzmi, dlaczego tak się dzieje i jak dostać się do zmiennych z klasy A, bezpośrednio z klasy D nie używając jednak wirtualizacji ani wskaźników (żeby zmienna a była jednoznaczna).

Jak także można się dostać, do zmiennej X w takiej funkcji (nie używając oczywiści funkcji wirtualnych ani wskaźników):

class X{
  public:
  int x;
};
class A: public X{
  public:
  int a;
};
class C : public A{
  public:
  int c;
};
class B : public A{
  public:
  int b;
};
class D : public B, public C{
  public:
  int d;
  int main()
  {
    D Obiekt;

    return 0;
  };



Nigdzie nie znalazłem odpowiedzi na te pytanie (ani w książkach, ani w internecie), więc był bym wdzięczny za pomoc jakiegoś doświadczonego programisty.

Data: 2007-12-15 12:24:33

Piotr Szawdyński


  • Klasa B dziedziczy po klasie A, więc klasa B ma interfejs klasy A i B.
  • Klasa C dziedziczy po klasie A, więc klasa C ma interfejs klasy A i C.
  • Klasa D dziedziczy po klasie B i C, więc ma interfejs klasy B i C i D. Ponieważ interfejs B i C dziedziczą po klasie A, to klasa D ma w konsekwencji interfejsy: (A+B) i (A+C) i (D).

To jest normalna i prawidłowa własność dziedziczenia.

Ty chciałbyś osiągnąć taki stan, że otrzymujesz wspólną zmienną a, która po dziedziczeniu należy osobno do klasy B i C, co jest fizycznie niemożliwe. Skąd kompilator ma wiedzieć, która zmienna jest prawidłowa na poziomie klasy D? Moim zdaniem jedyne co możesz zrobić w tym wypadku to utworzyć z klasie D zmienną int &a; i zainicjować ją tak, aby wskazywała na zmienną z interfejsu klasy B lub C. Szczegóły wykorzystania zapisu int &a; znajdziesz w rozdziale: http://ddt.pl/kursy/?LessonId=131

Aby dostać się do zmiennej w X, piszesz:

cout<<Obiekt::B::A::X::x;
Data: 2007-12-15 14:31:30

world007



cout<<Obiekt::B::A::X::x;
Niestety ten sposób nie działa.

Można do zmiennej x dostać się w taki sposób:
cout<<Obiekt.B::x;
Jednak to nie jest jednoznaczne, jak już napisałeś.

Ale jak się dostać powiedzmy do zmiennych z najstarszej klasy, z klasy najmłodszej, jeśli w dziedziczeniach występuje kilka "rozgałęzień", jak przez nie przejść jednoznacznie.

ps. Wiem że to wydumany problem, bo można po prostu użyć dziedziczenia wirtualnego, jednak na zajęciach wykładowca dał nam właśnie taki problem do rozwiązania.
(ciekawe czy wogóle da się to jakoś rozwiązać, czy to tylko podpucha z jego strony)

Data: 2007-12-15 14:31:34

world007


//sorki za dwa posty

Data: 2007-12-15 14:50:01

Piotr Szawdyński


wewnątrz klasy D możesz użyć chyba zapisu cout<<__super::a; lub cout<<__super->a; ale w momencie gdy dziedziszysz równolegle dwie klasy, to i tak nie będzie jednoznaczności, więc będziesz musiał podać ::B lub ::C.

__super działa chyba tylko pod visual studio.

Data: 2007-12-15 23:53:18

world007


ok, dzięki

tak więc nie jest to takie łatwe, powiem wykładowcy, że nie znalazłem tego czego chce, może mi powie o co mu chodziło wesoły

Data: 2007-12-16 11:47:57

Piotr Szawdyński


Jak będziesz miał odpowiedź od wykładowcy to napisz nam na forum wesoły Sam jestem bardzo ciekaw wesoły Może chodzi o dopisanie jakiegoś słowa kluczowego przy dziedziczeniu, skoro mówisz że wykładowca coś takiego wymyślił i mówi że się da...

Data: 2007-12-16 12:04:51

Piotr Szawdyński


Bez wykorzystania słowa kluczowego virtual nie wiem jak to zrobić.

#include <iostream>
using namespace std;
#include <conio.h>

class A{
  public:
  int a;
};
class C : virtual public A{
  public:
  int c;
};
class B : virtual public A{
  public:
  int b;
};
class D : public B, public C{
  public:
  int d;
};
int main()
{
  D Obiekt;
  Obiekt.B::a=999;
  cout << "Skladowa a od klasy B: " << Obiekt.B::a << endl;
  cout << "Skladowa a od klasy C: " << Obiekt.C::a << endl;
  Obiekt.B::a=132;
  cout << "Skladowa a od klasy B: " << Obiekt.B::a << endl;
  cout << "Skladowa a od klasy C: " << Obiekt.C::a << endl;
  getch();
  return 0;
}
12



Statystyki tematuOstatnio przeczytali
Czytało użytkowników:10malan, Dante, Matiz, ziemianp, pekfos, DeBugger, kiniro, listER, Piotr Szawdyński, Eliam
Przeczytało użytkowników:10
Czytało osób ogólnie:16
Przeczytało osób ogólnie:16



PowrótPowrótHistoria odwiedzonych stron
Panel Logowania
Login:
Hasło:

Użytkowników
Obecnie aktywnych:10
Zalogowanych:0
Zarejestrowanych:4367
Ostatnie 24h:720
Non-cookie 24h:2180
Wszystkich:214776
Ostatnia Aktualizacja
2010-09-01 19:27:34 (6 dni temu)
Ostatnio aktywni
fish133 godz
wiewiorka9 godz
Koni10 godz
BuZuz10 godz
Prezmen12 godz
trupank13 godz
szczgl14 godz
filipesq14 godz
KRIIS55116 godz
kuba181716 godz
extra217 godz
pixelmaster18 godz

Wynajem Sopot - wakacje
Pokój 2 osobowy 130zł/doba;
Lokalizacja: Sopot


O portaluArchiwumHistoriaIndeksRegulaminWyszukiwarkaLinki
Kurs HTML - strona WWW za darmoRestauracja "ATOL" - SopotValid HTML 4.01 TransitionalValid CSS!HTML CSS JavaScript FLASH PHP MySQL