Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475

    [C++] Undefined Reference to vtable

    Ciao a tutti...

    Stavo provando a realizzare un piccolo plagio di M$ su linux e mi sono imbattuto in questo errore (stavo cercando di implementare una classe Game come quella di XNA... fosse anche solo per vedere se avevo capito come funziona):

    codice:
    /home/michele/Programmazione/Game/GameTypes.h|52|undefined reference to `vtable for Game'|
    questo errore si verifica sul costruttore della classe Game

    codice:
    class Game
    {
        ... // variabili
        public:
    
        Game(int FPS = 60)
        {
            .. // inizializzazioni
        }
    
        virtual void LoadContent();
        virtual void Update();
        virtual void Draw();
        virtual void UnloadContent();
    }
    In realtà sono abbastanza sicuro di sapere che l'errore nasce da questa linea che crea un'istanza della classe derivata:

    codice:
    class TestGame : public Game
    {
         ...
         TestGame(int fps = 60) : Game(fps) { }
         ...
    }
    che sarebbe un tentativo di chiamare il costruttore della base class senza fare altro. Riesco senza problemi a istanziare la classe Game direttamente, ma istanziando la classe TestGame così:

    codice:
    game = new TestGame(60);
    ottengo l'errore detto sopra (game è dichiarato come TestGame*).

    Ho cercato su google (senza capirci molto, peraltro) cosa sia la vtable... e da quello che ho capito serve per i metodi virtuali. Ma il costruttore non è virtuale... quindi, perchè mi dice che non c'è la vtable di Game? :master:

    Update:

    Dopo aver smanacciato un po' sul codice tentando di risolverlo, ora non è più possibile istanziare Game direttamente.

    codice:
    Game* gameptr;
    gameptr = new Game(60);
    porta allo stesso errore di prima -.-
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  2. #2

    Re: [C++] Undefined Reference to vtable

    Il codice che hai inviato è incompleto, quindi è arduo darti un aiuto puntuale.
    In ogni modo: mancano i punti e virgola alla chiusura delle graffe nella dichiarazioni delle classi, ed il costruttore di TestGame (da quello che si vede) è privato.

  3. #3
    Utente di HTML.it L'avatar di Stoicenko
    Registrato dal
    Feb 2004
    Messaggi
    2,254
    credo che dovresti definire la classe Game come virtuale ponendo un metodo virtuale puro (di solito il distruttore) così da non complicarti la vita

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Sorry MacApp ^^

    E' solo che mi danno fastidio le sbrodolate di codice lunghe mezza pagina, perciò di solito tolgo tutte le parti che posso, o se sono poche righe lo riscrivo addirittura al momento (e da bravo programmatore C#, dimentico regolarmente di usare ; dopo una classe anche se nel programma c'è)

    Ecco il codice completo:

    main.cpp
    codice:
    #include <cstdlib>
    #include <SDL.h>
    #include <SDL/SDL_image.h>
    #include "GameTypes.h"
    
    bool RectsCollide(SDL_Rect r1, SDL_Rect r2);
    
    class TestGame : public Game
    {
        SDL_Event evento;
        bool tastiera[323];
        SDL_Rect screen;
    
        Sprite* bus;
        Sprite* roccia;
    
        public:
    
        TestGame(int fps = 60) : Game(fps) { }
    
        void LoadContent()
        {
            SDL_Rect screenSize = {0, 0, 1024, 768};
            screen = screenSize;
    
            this->RenderTarget = SDL_SetVideoMode( screen.w, screen.h, 32,
                                     SDL_HWSURFACE|SDL_DOUBLEBUF);
    
            bus = new Sprite(IMG_Load("bus.jpg"), 0, 0);
            roccia = new Sprite(IMG_Load("roccia.jpg"), 500, 0);
        }
    
        void Update()
        {
            while (SDL_PollEvent(&evento))
            {
                switch (evento.type)
                {
                case SDL_QUIT:
                    this->Exit();
                        break;
                case SDL_KEYDOWN: tastiera[evento.key.keysym.sym] = true;
                        break;
                case SDL_KEYUP: tastiera[evento.key.keysym.sym] = false;
                        break;
                }
            }
    
            if (tastiera[SDLK_ESCAPE]) this->Exit();
            if (tastiera[SDLK_UP]) bus->Rect.y -= 3;
            if (tastiera[SDLK_DOWN]) bus->Rect.y += 3;
            if (tastiera[SDLK_LEFT]) bus->Rect.x -= 3;
            if (tastiera[SDLK_RIGHT]) bus->Rect.x += 3;
    
            //Keeps the bus on the screen
            bus->ClampTo(screen);
    
            //Checks collision between the bus and the rock
            if (RectsCollide(bus->Rect, roccia->Rect)) this->Exit();
        }
    
        void Draw()
        {
            SDL_FillRect(
                this->RenderTarget,
                0,
                SDL_MapRGB(this->RenderTarget->format, 255, 255, 255));
    
            bus->Draw(this->RenderTarget);
            roccia->Draw(this->RenderTarget);
    
            SDL_Flip(this->RenderTarget);
        }
    };
    
    Game* game;
    
    int main ( int argc, char** argv )
    {
        //Starts the SDL system
        SDL_Init(SDL_INIT_EVERYTHING);
    
        game = new Game(60);
        game->Run();
    }
    
    bool RectsCollide(SDL_Rect r1, SDL_Rect r2)
    {
        if (r1.y + r1.h < r2.y
    	|| r1.y > r2.y + r2.h
    	|| r1.x + r1.w < r2.x
        	|| r1.x > r2.x + r2.w)
            return false;
        else
            return true;
    }
    GameTypes.h
    codice:
    #ifndef GAMETYPES_H_INCLUDED
    #define GAMETYPES_H_INCLUDED
    
    class Sprite
    {
        public:
    
        SDL_Surface* Texture;
        SDL_Rect Rect;
    
        Sprite(SDL_Surface* tex, int x, int y)
        {
            Texture = tex;
    
            Rect.x = x;
            Rect.y = y;
            Rect.h = tex->h;
            Rect.w = tex->w;
        }
    
        void Draw(SDL_Surface* window)
        {
            SDL_BlitSurface(Texture, NULL, window, &Rect);
        }
    
        void ClampTo(SDL_Rect area)
        {
            int areaR = area.x + area.w;
            int areaB = area.y + area.h;
    
            if (Rect.x < area.x) Rect.x = area.x;
            if (Rect.y < area.y) Rect.y = area.y;
            if ((Rect.x + Rect.w) > areaR) Rect.x = areaR - Rect.w;
            if ((Rect.y + Rect.h) > areaB) Rect.y = areaB - Rect.h;
        }
    };
    
    class Game
    {
        int fps;
        int frame_len;
        int lastUpdateCallTime;
        int timeDiff;
    
        bool runEnabled;
    
        public:
    
        SDL_Surface* RenderTarget;
    
        Game(int FPS = 60)
        {
            runEnabled = false;
    
            fps = FPS;
            frame_len = 1000 / fps;
            lastUpdateCallTime = 0;
            timeDiff = 0;
        }
    
        virtual void LoadContent();
        virtual void Update();
        virtual void Draw();
        virtual void UnloadContent();
    
        void Run()
        {
            LoadContent();
    
            while (runEnabled)
            {
                lastUpdateCallTime = SDL_GetTicks();
    
                Update();
                Draw();
    
                timeDiff = SDL_GetTicks() - lastUpdateCallTime;
                if(timeDiff < frame_len)
                    SDL_Delay(frame_len - timeDiff);
            }
        }
    
        void Exit(bool unloadContent = true)
        {
            runEnabled = false;
    
            if (unloadContent) UnloadContent();
        }
    };
    
    #endif // GAMETYPES_H_INCLUDED
    mmm... perchè avere Game come classe virtuale dovrebbe risolvere? Non ho capito :master:
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  5. #5
    Mancano le definizioni dei metodi della classe Game:
    codice:
        virtual void LoadContent();
        virtual void Update();
        virtual void Draw();
        virtual void UnloadContent();
    potresti renderli virtuali puri, ma in ogni modo dovresti definire anche il metodo UnloadContent nella derivata TestGame.

  6. #6
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    QUESTO è il motivo per cui sto passando a C++ da C#. E' troppo facile quando fa tutto .NET ^^

    Aggiunte le definizioni dei metodi (vuote) e ora funziona alla perfezione ^^
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.