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

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

11

10.07.2008, 16:46

Jupp, ich würde da auch zum Strategy Pattern (google hilft) greifen.
Über Vererbung lässt sich das nicht realisieren.

Viktor

Alter Hase

  • »Viktor« ist der Autor dieses Themas

Beiträge: 533

Wohnort: Ludwigshafen

Beruf: Student

  • Private Nachricht senden

12

10.07.2008, 17:24

Ich habe jetzt nochmal nachgelesen und es geht schon so wie Theprogrammer und Ba'el es vorgeschlagen haben. Nur mach ich gerade etwas falsch:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
    char input;
    Tier* animal = new Tier;
    SuperTier* SuTi = 0;

    animal->angreifen();
    cin >> input;
    SuTi = dynamic_cast<SuperTier*>(animal); // Das Tier wird in Supertier gecastet....(???)

    
    SuTi->angreifen();
    SuTi->verteidigen();

    cin >> input;
    
    return 1;
}

Der Compiler mekert dauernd, das Tier nicht Polymorph ist. Das weiß ich ja, aber was gibt es da zu meckern. ich mein, es muss doch nur SuperTier dann Polymorph sein, d.h. von Tier erben.

Ba'el

Alter Hase

Beiträge: 409

Wohnort: Erfurt

Beruf: Student (6 FS angew. Info. - Richtung Medieninformatik)

  • Private Nachricht senden

13

10.07.2008, 18:02

du musst einen static_cast verwenden

dynamic_cast kann man nur auf Klassen mit virtuellen Funktionen anwenden

allerdings hab ich es so gelernt das man den Destruktor einer vererbenden Klasse immer virtuell macht, und so könntest du auch wieder dynamic_cast anwenden
aktuelle Projekte:
Ruby on Rails
XNA &amp; Touchless
Progr. mobiler Endgeräte (GPS Trekking)

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

14

10.07.2008, 18:26

Zitat von »"Ba'el"«

du musst einen static_cast verwenden

edit


Warum hast du das wegeditiert? :)

Er bekommt nachher einfach ein anderes Problem, wenn das jetzt geht.
Er hat zwar einen Zeiger auf SuperTier, aber das Objekt dahinter ist (hier) nur ein Tier. Also obacht!

Ba'el

Alter Hase

Beiträge: 409

Wohnort: Erfurt

Beruf: Student (6 FS angew. Info. - Richtung Medieninformatik)

  • Private Nachricht senden

15

10.07.2008, 18:33

Zitat von »"drakon"«


Warum hast du das wegeditiert? :)


ich hatte selbst grad einen kleinen Denkfehler, hab ihn aber bereinigt

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
class a
{
public:
    virtual ~a(){}
    void mein(){}
};

class b : public a
{
public:
    void test(){}
};

void main()
{
    a* test = new a();
    b* super;

    super = dynamic_cast<b*>(test);

    super->test();
    super->mein();
}



oh, den Link hab ich ja auch wegeditiert, dass wollt ich eigentlich nicht
http://tutorial.schornboeck.net/dynamic_cast.htm
aktuelle Projekte:
Ruby on Rails
XNA &amp; Touchless
Progr. mobiler Endgeräte (GPS Trekking)

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

16

10.07.2008, 18:50

Finde ich immernoch gefährlich.

Was ist jetzt, wenn du in test auf Speicher zugreifst?

Ba'el

Alter Hase

Beiträge: 409

Wohnort: Erfurt

Beruf: Student (6 FS angew. Info. - Richtung Medieninformatik)

  • Private Nachricht senden

17

10.07.2008, 21:49

ich seh da nix gefährliches ... vielleicht bin ich auch nur abgestumpft weil ich die letzte Zeit durchweg Java programmieren musste ;P

edit:

ich hab's mal getestet, ist es sowas in der Art was dir sorgen macht

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
#include<iostream>
class a
{
public:
    virtual ~a(){}
    void mein(){std::cout<<"test"<<std::endl;}
};

a* pruef = new a();

class b : public a
{
public:
    void test(){delete pruef;pruef=NULL;}
};

void main()
{
    a* test = new a();
    b* super;
    
    super = dynamic_cast<b*>(test);

    test->mein();//wird ausgegeben

    super->mein();//wird ausgegeben

    pruef->mein();//wird ausgegeben

    super->test();//delete pruef

    if(pruef!=NULL)pruef->mein();//wird nicht ausgegeben

    super->mein();//wird ausgegeben

}


wenn du sowas mit Zugriff auf speicher meinst, das funktioniert ohne Probleme
aktuelle Projekte:
Ruby on Rails
XNA &amp; Touchless
Progr. mobiler Endgeräte (GPS Trekking)

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

18

10.07.2008, 22:10

Eher sows:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class a
{
public:
    virtual ~a(){}
    void mein(){}
};

class b : public a
{
    int* i;
public:
    b():i(0){
        i = new int;
    }
    ~b(){
        delete i;
    }

    void test(){std::cout << *i << std::endl;}
};


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
    a* test = new a();
    b* super;

    super = static_cast<b*>(test);

    super->test(); // buum

    super->mein();

    delete super; //räumt auch nicht richtig auf


Das Problem ist ja, dass du kein Objekt dieses Types hast, aber du tust so als ob. Somit kannst du Funktionen aufrufen, die auf nicht initialisierten Bereich zugreifen. (Was mit seehr hoher Wahrscheinlichkeit in der Wirklichkeit einmal passiert).
Dazu kommt auch noch, dass delete hier auch nicht das macht, was machen sich wünschen würde.

EDIT:
Wir waren ja mal bei static_cast. Mit dynamic_cast muss man hald noch dran denken zu überprüfen.

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

19

10.07.2008, 22:20

Das wird nur so lange ordentlich funktionieren wie deine beiden klassen binär kompatibel sind. Und ich denke, das ist nicht lange der fall.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class DummTier {
    int leben;
    DummTier() : leben(100) {}

    void test() {
        std::cout << leben << std::endl;
    }
};

class SchlauTier : public DummTier {
    int hirn;
    DummTier() :  hirn(10) {}

    void superTest() {
        // hirn nicht definiert
        std::cout << leben << ", " << hirn << std::endl;
    }
};

DummTier* tier = new DummTier(); 
tier->test(); // out << leben

SchlauTier* super = dynamic_cast<SchlauTier*>(tier);
super->superTest(); // undefinierte ausgabe.


Der SchlauTier Konstruktor wird nie aufgerufen. Genauso wenig wird die Variable hirn jemals irgendwo vorhanden sein. Damit kannst du dir ganz dicke Probleme einhalten. Der speicher des tierobjekts ist kleiner als der des SchlauTier objekts sein müsste, d.h. du wirst wild irgendwo in den Speicher schreiben.




[/code]

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

20

10.07.2008, 22:22

Zitat von »"xardias"«


Der SchlauTier Konstruktor wird nie aufgerufen. Genauso wenig wird die Variable hirn jemals irgendwo vorhanden sein. Damit kannst du dir ganz dicke Probleme einhalten. Der speicher des tierobjekts ist kleiner als der des SchlauTier objekts sein müsste, d.h. du wirst wild irgendwo in den Speicher schreiben.

Exakt. Mit dynamic_cast und anschliessendem Test, kann man das ja auch abfangen. (Macht so aber keinen Sinn, ausser er hat da mal einen downcast gemacht).

Werbeanzeige