• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Podwójne dziedziczenie z tej samej klasy - C++ SFML

Object Storage Arubacloud
0 głosów
1,127 wizyt
pytanie zadane 2 lipca 2017 w C i C++ przez DarkEliat Bywalec (2,810 p.)
edycja 2 lipca 2017 przez DarkEliat

Witam.

Sprawa wygląda mniej więcej tak: Mam kilka klas, klasę A, klasa B i C dziedziczą z A, a klasa D dziedziczy jednocześnie z B i C:

class A
{
public:
	char a;
};

class B : public A
{
public:
	char b;
};

class C : public A
{
public:
	char c;
};

class D : public C, public B
{
public:
	char d;
};

Do tego momentu wszystko jest spoko. Jednak w chwili kiedy chcę zrobić coś takiego:

D d;
d.a = 'a';

wyskakuje błąd C2385 - 'ambiguous access of 'a''. Jego naturę rozumiem. Chodzi o to, że kompilator nie wie czy mam na myśli nadanie wartości zmiennej B::a czy C::a. Jednak w moim programie muszą być te wszystkie klasy. B wykonuje czynności, których nie wykonuje klasa C, a klasa D musi dziedziczyć z nich obu.

Wiem, że w klasie D można dać coś takiego:

using B::a;
using C::a;

Z tego co widziałem działa to przy metodach, nie wiem czy przy obiektach także, ale nie chcę tak robić, bo musiałbym napisać z 30 takich linijek. Jest jeszcze możliwość napisać:

class A {};
class B : public A {};
class C : public B {};
class D : public C {};

Jednak to nie działa, ponieważ w kodzie używam szablonów klas i coś się kłóci, a na końcu wyskakuje błąd linkera: LNK2019

Oczywiście te klasy to tylko przykłady, zarys mojego obecnego kodu wygląda tak (Ponieważ używam SFML):

class sf::Transformable
{
public:
	void setPosition();
};

class sf::Sprite : public sf::Transformable
{
public:
	void openFromFile();
};

class Collidable : public sf::Transformable
{
public:
	bool isCollided();
};

class Player : public sf::Sprite, public Collidable
{
public:
	void shoot();
};

Jeśli coś nie jest jasne proszę pytać, wiem, że pewne, rzeczy wydają się być dziwne albo niezrozumiałe, ale nie sposób to wytłumaczyć nie pokazując całego kodu. Pozdrawiam.

1 odpowiedź

+1 głos
odpowiedź 2 lipca 2017 przez criss Mędrzec (172,590 p.)

Poczytaj o dziedziczeniu wirtualnym i problemie 'diamentowego dziedziczenia' (być może tak moge to nazwać po polsku :D). Tutaj 
A na szybko rozwiązaniem twojego problemu jest zamienić dziedziczenie klasy A w B i C na wirtualne.

komentarz 2 lipca 2017 przez DarkEliat Bywalec (2,810 p.)
Dzięki, wszystko wydawało się proste, ale mam problem. Jedną z klas (czyli w przykładzie B) jest sf::Sprite. Co prawda mam dostęp do pliku Sprite.hpp i mogę zmienić typ dziedziczenia na wirtualne, ale wtedy wyskakują błędy linkera: LNK2001 odnoszące się do destruktora sf::Sprite (chyba). Masz jakiś pomysł jak to rozwiązać?
komentarz 2 lipca 2017 przez criss Mędrzec (172,590 p.)
Skąd w ogóle pomysł, żeby dziedziczyć po sf::Sprite? To nie jest klasa napisana z myślą o dziedziczeniu po niej. sf::Sprite zamień na sf::Drawable. Ew. powiedz skąd taka potrzeba, to spróbujemy jeszcze coś wymyślić.
komentarz 2 lipca 2017 przez DarkEliat Bywalec (2,810 p.)
Dziedziczę po Sprite, ponieważ mam takie klasy jak Player, Enemy, Weapon i one wszystkie muszą się ostatecznie wyświetlać na ekranie, a dodatkowo każda z nich ma swoje własne metody i obiekty.
komentarz 2 lipca 2017 przez criss Mędrzec (172,590 p.)

 i one wszystkie muszą się ostatecznie wyświetlać na ekranie

Myślisz, ze do czego służy sf::Drawable? :D (PS: nazwa wiele mówi) SFML ma dość sensowne przykłady. Skorzystaj z nich.

komentarz 2 lipca 2017 przez DarkEliat Bywalec (2,810 p.)
Fakt, nazwy w SFML dużo mówią, ale obiekty, które wyświetlam na ekranie to obrazki pobrane z pliku. Jak zrobić to tylko przy pomocy klasy Drawable?
komentarz 2 lipca 2017 przez criss Mędrzec (172,590 p.)

Nie tylko przy pomocy sf::Drawable. Dziedziczysz po Drawable i nadpisujesz metode draw (o ile dobrze pamietam tak sie nazywala). Jednym z memberów twojej klasy jest sprite i go odpowiednio rysujesz w nadpisanej metodzie jak pokazano tutaj. Dodatkowo możesz dziedziczyć po sf::Transformable i wykorzystać sf::RenderStates, żeby nie musieć znowu pisać wszystkich tych getPosition, setPosition itd, jak pokazano tutaj

Mówiłem - skorzystaj z materiałów przygotowanych przez SFML. Teraz moja pomoc polega tylko na przeklejaniu ci linków jakbyś sam nie potrafił.

komentarz 2 lipca 2017 przez DarkEliat Bywalec (2,810 p.)
Ok, dzięki :) Myślę jednak, że problem tkwił w tym, że nie do końca rozumiałem zasadę działania Drawable, przeglądałem te linki i nie bardzo dawały mi one do myślenia, ale już ogarniam, więc wielkie dzięki. Mam tylko pytanie - czym to góruje nad dziedziczeniem ze Sprite (wyłączając oczywiście dzisiejsze główne pytanie)? Ostatecznie i tak muszę stworzyć obiekt Sprite, który i tak dziedziczy z Drawable i Transformable. A tak na koniec (jeśli masz czas i ochotę mi odpowiedzieć) To jak zrobiony jest ten Sprite, że wyświetla on obraz z pliku i ostatecznie nawet przy tworzeniu własnej "rysowalnej" klasy muszę go używać. Pozdrawiam.
komentarz 2 lipca 2017 przez criss Mędrzec (172,590 p.)

Tak został SFML zaprojektowany, żeby tak go używać. I w tym jest przewaga :P Rozwiązanie twórców chyba zawsze będzie lepsze niż błądzenie swoimi ścieżkami, nie sądzisz?

To jak zrobiony jest ten Sprite

SFML jest open-source. Wejdź na ich githuba i sobie poczytaj kod. 

Podobne pytania

0 głosów
1 odpowiedź 195 wizyt
pytanie zadane 31 marca 2018 w C i C++ przez miedziakk Nowicjusz (120 p.)
0 głosów
1 odpowiedź 83 wizyt
0 głosów
1 odpowiedź 474 wizyt

92,572 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...