Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

15.11.2014, 23:18

Kleine C++ Vererbungs Frage

Guten Abend!

Ich habe mich nun nach einer ersten Frage welche hilfreich beantwortet wurde daran gemacht ein paar Versuche mit C++ zu unternehmen. Allerdings bin ich jetzt schon auf ein Problem gestoßen: Anscheinend ist C++ ziemlich unterschiedlich von Javas.

Es geht darum, eine einfache Klasse "CollisionObject" zu haben, welche von anderen Klassen als Superklasse benutzt werden kann.

Nach meinen Versuchen die Vererbung C++ konform zu machen sieht es nun wie gefolgt aus, wirft allerdings immer noch einen Fehler aus; Nämlich "ein Vererbter Member ist nicht zulässig".

CollisionObject.h

Quellcode

1
2
3
4
5
6
7
8
9
10
class CollisionObject {
protected:
    sf::Shape* shape;
    virtual void assignShape() = 0;
public:
    CollisionObject(){
        assignShape();
    }

};


Platform.h

Quellcode

1
2
#include "CollisionObject.h"
class Platform : CollisionObject {};


Platform.cpp

Quellcode

1
2
3
4
5
6
7
8
9
10
#include "Platform.h"

Platform::Platform() : CollisionObject() {
    assignShape();
}

void Platform::assignShape(){ //Fehler liegt hier. Soweit ich es verstanden habe muss man den Körper einer Methode ja deklarieren per "returntype class::method"-Struktur. Allerdings meldet VS mir hier den oben genannten Fehler.
    shape = &sf::CircleShape(5);
    std::cout << "Platform#assignShape\n"; // Ich will wissen ob die assignShape Funktion eins oder zwei Mal aufgerufen wird. Der Logik nach sollte sie ja 2mal aufgerufen werden da ich sie 4 Zeilen drüber aufrufe aber ich will sicher gehen.
}


Auch wenn ihr euch jetzt bei diesem Code jetzt wahrscheinlich alle die Kopfe schüttelt, würde ich mich extrem über eine Antwort freuen :) !

Mit freundlichen Grüßen,

Darkium

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

2

15.11.2014, 23:29

Du musst in der Klasse auch sagen, dass du die Eltern-Methode überschreiben willst.
Statt:
class Platform : CollisionObject {};
das:

C-/C++-Quelltext

1
2
3
4
class Platform : CollisionObject {
public:
void assignShape() /*override*/;
};


override existiert erst seit C++11, aber wenn du C++11 nutzt (-std=c++11, -std=c++0x oder -std=c++1y als Compiler Flag) ist es ratsam, es zu benutzen.

edit:
Oh, gut das ich nochmal rüber gucke: Du versuchst außerdem, den Konstruktor von Platform zu definieren, ohne ihn deklariert zu haben.
Es fehlt also ein Platform(); in der entsprechenden Klasse.
Dir fehlen einige bedeutende Grundlagen, die solltest du dringend aufarbeiten, bevor du mit der SFML anfängst.

edit 2:
Der Aufruf der virtuellen Methode im Konstruktor von CollisionObject ist nicht allzu klug. Das "warum" überlasse ich aber mal dir. :)
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Architekt« (15.11.2014, 23:38)


3

15.11.2014, 23:32

Vielen Dank für die Antwort, ich werde es morgen probieren!

4

15.11.2014, 23:35

Es ist nicht ratsam, virtuelle Methoden im Basisklassenkonstruktor aufzurufen. Siehe hier

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

16.11.2014, 08:49

Jo, solange man kein Swift macht, sollte man das unbedingt vermeiden.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

6

16.11.2014, 11:54

Noch eine Anmerkung, auch wenn es in dem Beispiel möglicherweise auch so geht:
C++ unterstützt private Vererbung. Also auf die Basisklasse kann nur von der abgeleiteten Klasse zugegriffen werden, ansonsten ist es, von außen sieht es aus, als ob es keine Basisklasse gäbe. (Ganz ähnlich halt zu normalen privaten Membern).
C++ ist das bei Klassen das Standardverhalten, wahrscheinlich willst du alles das erreichen: (So wie es auch in Java immer ist.)

C-/C++-Quelltext

1
2
class Platform : public CollisionObject //Die Vererbung von der Basisklasse öffentlich sichtbar machen.
{};

7

16.11.2014, 13:38

@Architekt
Vielen Dank für die Antwort. VS zeigt mir nun keine Fehlermeldung mehr an.

@Roflo
Oha... Das macht das ganze irgendwie viel komplizierter. Ich will nämlich erreichen, dass die assignShape() Funktion in der Subklasse deklariert werden muss, aber automatisch aufgerufen wird ohne dass der "Ersteller" der Subklasse etwas tun muss. Die Lösung von dem Link den du gepostet hast passt da leider überhaupt nicht, da der Code quasi eine weitere Methode benötigt und etwas als Parameter übergibt - Was ich theoretisch natürlich machen könnte, aber wo ich jetzt schon dabei bin eigentlich vermeiden will. Gibt es keine andere Lösung?

@Spiele Programmierer
Oh, vielen Dank, ist mir gar nicht aufgefallen!


Mit freundlichen Grüßen
Darkium

8

16.11.2014, 15:55

Für dein Problem gibt es eigentlich eine relativ einfache Lösung: Schmeiß die Methode raus und pack den Inhalt direkt in den Konstruktor. Warum willst du dafür überhaupt ne extra Methode?
"Theory is when you know something, but it doesn’t work. Practice is when something works, but you don’t know why. Programmers combine theory and practice: Nothing works and they don’t know why." - Anon

9

16.11.2014, 16:09

Weil der Code je nach Subklasse anders sein soll. Daher soll die CollisionObject-Klasse und assignShape-Methode abstrakt sein.

10

16.11.2014, 16:21

Der Konstruktor einer abgeleiteten Klasse wird nach dem der Basisklasse aufgerufen. Passt doch

Werbeanzeige