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

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

1

14.07.2013, 22:15

Vererbung und Container

Ich habe eine Basisklasse und mehrere Unterklassen.
Das Problem ist nun, wie ich diese in einen einzigen Container bekomme.

In diesem Fall handelt es sich um Dialogs:

C-/C++-Quelltext

1
2
std::vector<Dialog> dialogs;
dialogs.push_back(menu);


das obrige klappt nicht. Selbstverständlich erstelle ich auch die Klassen usw :D

Gibt es überhaupt eine Möglichkeit, die dann alle in einen Container zu packen oder mache ich was falsch und ihr braucht mehr Code?

EDIT: Das gleiche Prinzip würde ich gerne auf mehrere Sachen anwenden, zB verschiedene Arten von Buttons in einem Container. (Welche die "nur" aus Schrift bestehen und welche die aus einem Bild bestehen )

2

14.07.2013, 22:18

habe auch an einem system gearbeitet, gegner über einen Vektor zu überprüfen


es klappt mit dynamik cast und virtual gesetzten funktionen innerhalb der klasse


Schau dir mal dynamic cast an und virtuelle funktionen

3

14.07.2013, 22:31

Also du hast eine Basisklasse und Unterklassen die ableiten von dieser

Um eventuelle funktionen zu benutzen die es nur in den Unterklassen gibt ist das stichwort dynamic cast.
Bei überschreibung der funktionen sprich, wenn deine Buttons alle die funktion Use haben und diese sich voneinander unterscheiden, ist für dich wichtig, in deiner Basisklasse die funktion Use virtual zu deklarieren, das heißt, das diese funktion eventuell von einer anderen Klasse (unterklasse) überschrieben wird.


Zu dem Problem mit dem vector das ist auch eignt nicht ganz so schwer, jedenfalls nicht, wenn man sich mit beschäftigt.


Sagen wir du hast die Basisklasse Raumschiff und die Unterklasse Jaeger.

Nun würde das ganze so aussehen, wenn du diesen Typ in einen Vektor des Typs Raumschiff reinpacken wolltest.

C-/C++-Quelltext

1
2
3
4
vector<CRaumschiff> m_Enemies;
CRaumschiff * Schiff;
Schiff = new CJaeger;
Enemies.push_back(*Schiff);

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

4

14.07.2013, 22:32

Du kannst nur die Pointer in einen Container tun, da Instanzen abgeleitetender Klassen physikalisch anders aussehen.

H5::

Treue Seele

Beiträge: 368

Wohnort: Kiel

  • Private Nachricht senden

5

15.07.2013, 03:52


C-/C++-Quelltext

1
2
3
4
vector<CRaumschiff> m_Enemies;
CRaumschiff * Schiff;
Schiff = new CJaeger;
Enemies.push_back(*Schiff);
Das wird wahrscheinlich nicht zum gewünschten Ergebnis führen. Auch wenn du einen Zeiger erzeugst, so dereferenzierst du ihn gleich wieder. Danach kopierst! du nur die CRaumschiff Bestandteile von CJaeger in den Vector. Dieses Absäbeln nennt man object slicing und hat zur Folge, dass man zum einen ein neues Object hat, eine nicht vollständige Kopie durchführ und es somit mit keinem Cast oder sonst etwas gibt um vom Vektor auf das Original zu zu greifen ( Was, so wie ich es verstanden habe ja genau gewollt ist. Bzw. zumindest auf die CRaumschiff Teile vom Jäger).
namespace

Beispiel Klassen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
namespace
{
    /// <summary>sample A</summary>
    class A
    {
    private: // -- member
        int a_;

    public:  // -- CTor's/DTor
        A( int a = 0 ) : a_( a ) { };

    public:  // -- named params
        virtual auto a( int value ) -> A& { a_ = value; return *this; };
        virtual auto a( ) const -> int { return a_; };
    };

    /// <summary>sample B</summary>
    class B : public A
    {
    private: // -- member
        int b_;

    public:  // -- CTor's/DTor
        B( int b = 0 ) : b_( b ) { };

    public:  // -- named params
        virtual auto b( int value ) -> B& { b_ = value; return *this; };
        virtual auto b( ) const -> int { return b_; };
    };

}


Schlechte Beispiele:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <summary>entry point</summary>
auto main( int argc, char** argv )
    -> int
{
    using std::vector;

    vector<A> va;
    auto bp = new B;     // delete nicht vergessen! Lieber smart pointer nutzen.
    va.push_back( *bp ); // !!! Nicht so gut, object slicing
    // dynamic_cast<A>( va.at( 0 ) ); // geht nicht! nur per Referenz
    auto b_wie_boese = dynamic_cast<B*>( &va.at( 0 ) );
    auto result = b_wie_boese->b( ); // Access violation

    // ist genauso wie:
    auto bv = B( );
    va.push_back( bv );  // hier wird auch der B Teil abgeschnitten.

    delete bp;
    return 0;
}


Besser z.B. so:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/// <summary>entry point</summary>
auto main( int argc, char** argv )
    -> int
{
    using std::vector;

    vector<std::unique_ptr<A>> va;
    {
        auto b = std::unique_ptr<B>( new B );
        va.push_back( std::move( b ) ); // Objekt bleibt erhalten.
    }
    // oder
    va.push_back( std::unique_ptr<B>( new B ) );

    auto& result = dynamic_cast<B&>( *va.at( 0 ) ); // EDIT: Zugreifen kann man z.B. so.

    return 0;
}


Wikipedia Object slicing
:love: := Go;

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »H5::« (15.07.2013, 04:08)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

15.07.2013, 07:19

Nun würde das ganze so aussehen, wenn du diesen Typ in einen Vektor des Typs Raumschiff reinpacken wolltest.

C-/C++-Quelltext

1
2
3
4
vector<CRaumschiff> m_Enemies;
CRaumschiff * Schiff;
Schiff = new CJaeger;
Enemies.push_back(*Schiff);

Das strotzt nur so vor Problemen. Der größte neben schon erwähnter Kopie ist wohl, dass Du das Objekt auch gleich im Stack ohne new erzeugen könntest und dass Du effektiv danach ein Speicherloch hast, da Du den Jaeger nicht löschst. Gruseliger Code mit ganz gruseligem Verhalten.
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]

Werbeanzeige