[C++] Method in een class vervangen @ runtime

Pagina: 1
Acties:

  • The Wrecker
  • Registratie: Juli 2002
  • Laatst online: 20-04 23:05

The Wrecker

Networking Rulez

Topicstarter
Ik zit met het volgende probleem,

Ik maak een serie van verschillende objecten van hetzelfde type. het huidige object waar ik mee ga werken daar heb ik een pointer van(de rest staat in een array). Ik moet dus ook kunnen wisselen tussen de verschillende objecten in de array (gaat prima aanpassen pointer).

Nu is het zo dat elk object z'n eigen eiegnschappen heeft en ik wil niet vergelijken wat voor soort object het eigenlijk is. Is er een manier om een gehele method als het ware te herschrijven als je het object aanmaakt of instantieert?

Ik heb zelf gezocht hier op tweakers en google, maar ik kreeg continu object/inheritace gerelateerde spullen. In elk geval niet wat ik zoek. Het is een op zichzelf staand object(overerft niets)

  • whoami
  • Registratie: December 2000
  • Laatst online: 11:02
Ik snap niet zo goed wat je bedoelt ?
Je hebt dus een aantal objecten (van hetzelfde type ? ), en dan wil je een bepaalde eigenschap aanspreken ? Aangezien alle objecten van hetzlfde type zijn, weet je toch ook welke eigenschappen die hebben ?

https://fgheysels.github.io/


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

voor zover ik weet heb je 2 mogelijkheden:
1) object/inheritance.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A
{
   virtual void myMethod();
}
class B : A
{
  virtual void myMethod();
}

int main()
{
  A* obj = new B();
  A->myMethod(); // effectief B->myMethod() afaik
}

of je werkt met scenario's die je hardcodeert in je class

C++:
1
2
3
4
5
6
7
8
class A
{
   A(void (*myScenarioMethod)());
   myMethod()
   {
      myScenarioMethod();
   }
}

(niet zo'n mooie oplossing)
of
C++:
1
2
3
4
5
6
7
8
9
10
11
class A:
{
    friend void ScenarioMethod1(A* obj);
    protected int myState;
}

void ScenarioMethod1(A* obj)
{
   if (a->myState & goeieState)
      //doe iets met A
}


dit zijn de eerste 2 dingen die in me op komen

[ Voor 3% gewijzigd door H!GHGuY op 19-11-2005 17:55 ]

ASSUME makes an ASS out of U and ME


  • Daos
  • Registratie: Oktober 2004
  • Niet online
Je moet het gewoon met inheritance doen. Tip: In C++ zit een keyword dat "virtual" heet.

Je kan waarschijnlijk ook iets doen met functie pointers, maar dat werkt lang niet zo makkelijk als inheritace.

[edit]
Te laat...
offtopic:
Ik moet toch maar eens mijn typcursus overdoen. Ik heb meer dan 4 minuten nodig voor 2 zinnetjes.

[ Voor 35% gewijzigd door Daos op 19-11-2005 18:04 ]


  • The Wrecker
  • Registratie: Juli 2002
  • Laatst online: 20-04 23:05

The Wrecker

Networking Rulez

Topicstarter
owk even een visualisering

C++:
1
2
3
4
5
6
7
8
9
10
11
12
class Weapon
{
public:
     
    class GameAudio *gameAudio;
    int initammo; //max ammo dat een wapen kan hebben
    int currentammo; // huidige hoeveelheid
    void shoot(int helth,int armor)
    {
        ... code
    }
};


een klein stukje van de code. Het gaat dus over een wapen class(3d shooter). Ik geef op aan de class wat voor wapen het moet zijn en aan de hand daarvan word de mesh geladen e.d. Nu zou ik willen dat de shoot methode eigenlijk aangepast word aan het wapen dat ik aan de class opgeef. Of dat ik een string heb die de naam van de aan te roepen methode bevat.

Je hebt gelijk als je zegt dat ik eigenlijk verschillende objecten moet maken van de verschillende wapen en de algemen wapen class dan kan overerven, maar dat is even niet wat ik wil. (omdat ik dan verschillende typen objecten heb)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:12

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik heb zelf gezocht hier op tweakers en google, maar ik kreeg continu object/inheritace gerelateerde spullen. In elk geval niet wat ik zoek
Waarom niet? Met virtual methods kun je alle objecten hetzelfde behandelen, en de daadwerkelijke functie die aangeroepen wordt hangt af van het type van het object. En als je dan het type van een van die objecten moet veranderen kun je natuurlijk ook gewoon het object vervangen door één van een ander type.

En als je dan toch per se 1 specifieke methode aan wil kunnen passen tijdens runtime kun je ook gewoon functionpointers gebruiken.
The_Wrecker schreef op zaterdag 19 november 2005 @ 17:59:
Je hebt gelijk als je zegt dat ik eigenlijk verschillende objecten moet maken van de verschillende wapen en de algemen wapen class dan kan overerven, maar dat is even niet wat ik wil. (omdat ik dan verschillende typen objecten heb)
Maar wáárom is dat dan vervelend, dat het objecten zijn van verschillende typen? Je kunt toch gewoon een pointer houden naar Weapon, terwijl hij eigenlijk wijst naar een Shotgun maar zonder dat je daar vanaf hoeft te weten?

[ Voor 33% gewijzigd door .oisyn op 19-11-2005 18:03 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • The Wrecker
  • Registratie: Juli 2002
  • Laatst online: 20-04 23:05

The Wrecker

Networking Rulez

Topicstarter
.oisyn schreef op zaterdag 19 november 2005 @ 17:59:
[...]
Maar wáárom is dat dan vervelend, dat het objecten zijn van verschillende typen? Je kunt toch gewoon een pointer houden naar Weapon, terwijl hij eigenlijk wijst naar een Shotgun maar zonder dat je daar vanaf hoeft te weten?
Uhm , ik maak een pointer naar het object, maar moet die pointer dan niet van datzelfde type zijn? en dan heb ik een array van die objecten. Ik kan toch niet verschillende objecten in die array mixen of wel?

Ik ken Java en objecten e.d. wel, maar ik weet niet hoe vergevingsgezind c++ is. Overigens werk ik al een tijdje met c++, maar veel dingen weet ik nog niet. (ik kan zelfs zeggen dat ik weer in Java moet komen als ik daar mee ga beginnen)

[ Voor 21% gewijzigd door The Wrecker op 19-11-2005 18:07 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:02
The_Wrecker schreef op zaterdag 19 november 2005 @ 17:59:
owk even een visualisering

een klein stukje van de code. Het gaat dus over een wapen class(3d shooter). Ik geef op aan de class wat voor wapen het moet zijn en aan de hand daarvan word de mesh geladen e.d. Nu zou ik willen dat de shoot methode eigenlijk aangepast word aan het wapen dat ik aan de class opgeef. Of dat ik een string heb die de naam van de aan te roepen methode bevat.

Je hebt gelijk als je zegt dat ik eigenlijk verschillende objecten moet maken van de verschillende wapen en de algemen wapen class dan kan overerven, maar dat is even niet wat ik wil. (omdat ik dan verschillende typen objecten heb)
Dat is dus idd gewoon een geval 'polymorphisme', en dat moet je met inheritance / virtual methods oplossen.
Je hebt een class Weapon, die een virtual method shoot heeft. Van Weapon inherit je 'Pistol', 'MachineGun', etc..., en je override iedere keer de shoot method, zodat je een specifieke shoot - method hebt per wapen.

In je programma heb je dan bv een collectie / array van 'Weapons', waar er bv een Pistol en een MachineGun inzit:

code:
1
2
3
4
weaponArray[0] = new Pistol();
weaponArray[1] = new MachineGun();
weaponArray[0].Shoot(); // Hier wordt de shoot-method van pistol uitgevoerd
weaponArray[1].Shoot(); // machinegun::shoot wordt uitgevoerd


Maar, dan moet je dus wel een virtual method Shoot hebben in de class Weapon, en override die method in Pistol en MachineGun.
Uhm , ik maak een pointer naar het object, maar moet die pointer dan niet van datzelfde type zijn? en dan heb ik een array van die objecten. Ik kan toch niet verschillende objecten in die array mixen of wel?
Aangezien Pistol en MachineGun van Weapon inheriten, zijn het 'Weapons', en kunnen ze dus in een array van Weapons gestopt worden.
(Zoek eens op polymorphisme / late binding).

[ Voor 12% gewijzigd door whoami op 19-11-2005 18:08 ]

https://fgheysels.github.io/


  • The Wrecker
  • Registratie: Juli 2002
  • Laatst online: 20-04 23:05

The Wrecker

Networking Rulez

Topicstarter
owk,

ik ga zo eens even kijken of ik eruit kan komen. heb nooit zozeer met vritual methods gewerkt, maar het lijkt mij hier wel de beste oplossing inderdaad.

Door het hebben van verschillende objecten was ik ook niet zeker of dat hetgene is wat ik wil hebben. Toch kijk ik ook nog even naar functie pointers.

[ Voor 34% gewijzigd door The Wrecker op 19-11-2005 18:16 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:12

.oisyn

Moderator Devschuur®

Demotivational Speaker

whoami schreef op zaterdag 19 november 2005 @ 18:07:
code:
1
2
3
4
weaponArray[0] = new Pistol();
weaponArray[1] = new MachineGun();
weaponArray[0].Shoot(); // Hier wordt de shoot-method van pistol uitgevoerd
weaponArray[1].Shoot(); // machinegun::shoot wordt uitgevoerd
Even opletten, dit is C# code. In C++ is weaponArray een array van pointers naar Weapon, Oftewel een Weapon** (of nog beter, een std::vector<Weapon*>). De Shoot() methode zal dan ook aangeroepen moeten worden met een pijl (->) ipv een punt (.)

[ Voor 24% gewijzigd door .oisyn op 19-11-2005 18:50 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • The Wrecker
  • Registratie: Juli 2002
  • Laatst online: 20-04 23:05

The Wrecker

Networking Rulez

Topicstarter
Sorry,

Ik krijg het nog niet goed voor elkaar. Ik denk dat het de bedoeling is dat het direct in een pointer gestopt word en dat heb ik dus niet. mijn array word op deze manier aangemaakt:
Weapon weapon[4];
Kan ik hiermee verder werken of kan ik dan beter een array met pointer maken? Of wellicht een andere oplossing gebruiken.

ik doe vervolgens dit:
C++:
1
2
3
4
5
6
    weapon[0] = new Knife(smgr,gameAudio);
        weapon[1] = Knife(smgr,gameAudio);
        weapon[2] = Knife(smgr,gameAudio);
        weapon[3] = Knife(smgr,gameAudio);
        currentWeapon = &weapon[weaponid];
        currentWeapon->Select();


maar op de new krijg ik dus een foutmelding (haal ik die weg dan pakt hij alsnog de nieuwe methode niet.)
foutmelding van de compiler:
c:\Programming\game\Player.h(69): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Knife *' (or there is no acceptable conversion)

lijkt erop dat ie wil dat het een pointer is dus

[ Voor 49% gewijzigd door The Wrecker op 19-11-2005 19:13 ]


  • zeroxcool
  • Registratie: Januari 2001
  • Laatst online: 13-04 20:00
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Weapon * weapon[4];
Weapon * currentWeapon;

weapon[0] = new Weapon();
weapon[1] = new Weapon();
weapon[2] = new Weapon();
weapon[3] = new Weapon();

currentWeapon = weapon[weaponid];
currentWeapon->Select();

// of:

weapon[weaponid]->Select();

Kun je dan idd beter gebruiken. Of, nog beter, zoals oisyn een vector voor je weapons.

[ Voor 23% gewijzigd door zeroxcool op 19-11-2005 19:17 . Reden: currentweapon code toegevoegd ]

zeroxcool.net - curity.eu


  • The Wrecker
  • Registratie: Juli 2002
  • Laatst online: 20-04 23:05

The Wrecker

Networking Rulez

Topicstarter
Ok Bedankt mensen,

Dit is mijn uiteindelijke code:
C++:
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
class Weapon
{
public:
     
    class GameAudio *gameAudio;
    int initammo; //max ammo dat een wapen kan hebben
    int currentammo; // huidige hoeveelheid
    int strength; //wapen sterkte
    int range;//wapen afstand
    virtual int Shoot(int targetHealth, int armor, core::vector3df targetPosition)
    {
        return 100;
    }
};
class Knife : public Weapon
{
public:
    Knife(scene::ISceneManager* smgr1,GameAudio *gameAudio1)
    {
        this->smgr=smgr1;
        this->gameAudio = gameAudio1;
    }
    
    int Shoot(int targetHealth, int armor, core::vector3df targetPosition)
    {
        gameAudio->Knife();
        return 0;
    }
};

De array maak ik aan zoals hierboven staat aangegeven. Voor mij werkt dit en het is nog eens netjes OOP ook. :)

[ Voor 4% gewijzigd door The Wrecker op 19-11-2005 20:18 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:02
.oisyn schreef op zaterdag 19 november 2005 @ 18:49:
[...]

Even opletten, dit is C# code. In C++ is weaponArray een array van pointers naar Weapon, Oftewel een Weapon** (of nog beter, een std::vector<Weapon*>). De Shoot() methode zal dan ook aangeroepen moeten worden met een pijl (->) ipv een punt (.)
Idd. 't Is dan ook al 10 jaar geleden dat ik iets in C++ gedaan heb.

https://fgheysels.github.io/


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:12

.oisyn

Moderator Devschuur®

Demotivational Speaker

The_Wrecker schreef op zaterdag 19 november 2005 @ 19:48:
De array maak ik aan zoals hierboven staat aangegeven. Voor mij werkt dit en het is nog eens netjes OOP ook. :)
Ik zou die Weapon::Shoot pure maken (door 'm geen implementatie te geven maar = 0; achter de functiedeclaratie te zetten), hij heeft immers geen zinnige implementatie en zo dwing je een afgeleid wapen die methode te implementeren

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1