Scholieren.com forum

Scholieren.com forum (https://forum.scholieren.com/index.php)
-   Software & Hardware (https://forum.scholieren.com/forumdisplay.php?f=20)
-   -   [C++] Abstracte klasses (https://forum.scholieren.com/showthread.php?t=1546258)

Jordi 21-02-2007 00:38

[C++] Abstracte klasses
 
Ik ben net weer begonnen aan een wat groter project in C++ en toen kwam ik er ineens weer achter dat er geen interfaces bestaan en dat je klasses niet explicitiet abstract of virtual kan maken. De compiler kijkt namelijk zelf of een klasse abstract is door te kijken of hij pure virtuele methodes bevat.
Op zich is dat nog niet zo'n heel erg groot probleem, maar wat wél erg vervelend is, is dat als een klasse abstract is bevonden, ik hem zoals het er nu naar uitziet niet mag gebruiken als parameter- of return-type.

Ik ben een spelletje aan het maken waarbij verschillende soorten Players mee kunnen doen. De enige eis aan zo'n Player is dat hij een aantal methodes als makeMove() (of predict()) implementeert zodat de GameEngine die aan kan roepen, hoe de Player bepaalt welke zet hij gaat doen, verschilt per soort.

Voorbeeldje:
Code:

class Player
{
public:
      virtual int predict () = 0; // pure virtual function
};

class GameEngine
{
public:
      GameEngine (Player p): player(p), number(rand()%10) {}
      int test () {
          const int p = player.predict();
          if (number == p) return 0;
          if (number < p) return -1;
          return 1;
      }
private:
        int number;
        Player player;
};

En nog een voorbeeldje van een speler en een aanroep:
Code:

class IdiotPlayer : public Player
{
public:
      int predict () { return 1; }
};

int main () {
    IdiotPlayer idiot;
    GameEngine e (idiot);
    system("PAUSE");
    return EXIT_SUCCESS;
}

Heeft iemand enig idee hoe ik zoiets kan doen in C++?

Fietspomp_bv 22-02-2007 00:23

Even een paar simpele vragen:
Welke compiler gebruik?
Welke error krijg je precies?
En heb je gemakshalve de constructer van de player en idiotplayer class weggelaten, of ben je het vergeten?

Jordi 22-02-2007 01:14

Bedankt voor je reactie. Ik heb het probleem al opgelost, maar ik zal de antwoorden op je vragen en de oplossing nog wel even posten zodat iemand er misschien ooit nog wat aan heeft om dit topic te lezen:
Compiler: Volgens mij GNU GCC (de default compiler van Dev-C++ en Code::Blocks)
Errors:
Citaat:

cannot declare parameter `p' to be of type `Player' because the following virtual functions are abstract: virtual int Player:: predict()
cannot declare field `GameEngine:: player' to be of type `Player' since type `Player' has abstract virtual functions
In function `int main()':
cannot allocate an object of type `Player' since type `Player' has abstract virtual functions
Constructors: In het voorbeeld heb ik ze voor het gemak weg gelaten en omdat ze ook niet nodig zijn. Dat is in dit geval natuurlijk alleen maar zo, omdat de default constructor die geen argumenten heeft en niets doet volstaat.

De/Een oplossing is blijkbaar om geen echte instanties van type Player te gebruiken, maar pointers. Waarom dit zo is, snap ik niet helemaal, maar het zal er wel iets mee te maken hebben dat er bij een pointer niet wordt geprobeerd om meteen de default constructor van een klasse aan te roepen en anders wel. De werkende code van het voorbeeld:

Code:

class Player
{
public:
      virtual int predict () = 0; // pure virtual function
};

class GameEngine
{
public:
      GameEngine (Player* p): player(p), number(rand()%10) {}
      int test () {
          const int p = player->predict();
          if (number == p) return 0;
          if (number < p) return -1;
          return 1;
      }
private:
        int number;
        Player* player;
};
     
class IdiotPlayer : public Player
{
public:
      int predict () { return 1; }
};

int main () {
    Player* idiot = new IdiotPlayer;
    GameEngine e (idiot);
    system("PAUSE");
    return EXIT_SUCCESS;
}


Fietspomp_bv 22-02-2007 22:50

De reden dat je een pointer moet gebruiken, is omdat je geen Player object kan creëren (zoals je compiler je vertelt). Als je een normaal player object of een reference wilt in je functie, wordt er dus gebruik gemaakt van een instance van dat object, en dat gaat niet. Met een point heb je dat echter niet, die verwijst naar een stuk geheugen waar iets staat dat lijkt op Player (in dit geval IdiotPlayer). Via deze manier maak je dus gebruik van een IdiotPlayer class in plaats van een Player class, en dat mag wel.

Ik hoop dat het een beetje duidelijk is :P

Jordi 23-02-2007 01:48

Ah, zoiets dacht ik al. Bedankt voor je reactie!

Fietspomp_bv 23-02-2007 13:37

np


Alle tijden zijn GMT +1. Het is nu 21:13.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.