Skip to main content
gamedev.net
🔒 Locked 🎮 Unity

Compiler/Linker problem (DevC++/mingw)

Started by wortel 0 replies 1.2k views
Original Post
wortel
wortel
Hi, Basically, I'm writing a 2D networked arcade type game, with players shooting each other soldat - style, using Allegro and Enet, but I'm having a lot of trouble getting my program to compile using Dev-C++/ Mingw. I really think I've tried everything, but I keep on getting the following error: [Linker error] undefined reference to `vtable for S_Object' I have no idea what a vtable is (i'm inexperienced with c++), but AFAIK I'm doing everything right. The compiler log gives the following:

  Compiler: Default compiler
Building Makefile: "C:\Dev-Cpp\stick\Makefile.win"
Executing  make...
make.exe -f "C:\Dev-Cpp\stick\Makefile.win" all
g++.exe Server.o Arena.o Client.o main.o S_Client.o Warrior.o S_Object.o Project1_private.res -o "Project1.exe" -L"C:/Dev-Cpp/lib" -mwindows -lalleg -lenet -lws2_32 -lwinmm  S_Object.o(.text+0x8):S_Object.cpp: undefined reference to `vtable for S_Object'
S_Object.o(.text+0x16):S_Object.cpp: undefined reference to `vtable for S_Object'
collect2: ld returned 1 exit statusmake.exe: *** [Project1.exe] Error 1Execution terminated

I don't want to include too much source with this, but since i can't find anything wrong with S_Object.h/S_Object.cpp, and I'm guessing that the problem lies with the class thats derived from them, I'm going to include all four, so bear with me :) Both the client and server uses these classes to represent objects, although they have different functions to perform operations on them. I know, this might not necessarily be the best way to do it, but I think it's nice and structured. I've mangled them a bit, trying to find the problem, S_Object used to be abstract but that didn't make a difference, I got the same problem. Ok, S_Object.h:

#ifndef S_OBJECT_H
#define S_OBJECT_H

class S_Object       //abstraction for all object stored in list
{
      public:
             S_Object();
             int getID();
             
          
             
             S_Object *next;
             bool removeMe;
             int ID;
             
             //Serverside only
             virtual void Supdate();
             virtual int pack(char*);//pack hele object
             void netPack(void* addr,int n,char*buff,int counter);        //pack 'n variable
             
             
             //Clientside
             virtual int netUpdate(char*);
             virtual void update();
             void netRead(void* addr,int n,char*buff,int counter);
             
             
             
      protected:
                int type;
                float xpos;
                float ypos;
                int dir;
                
                int status;
                
};
#endif

S_Object.cpp :

/*
Shared S_Object functions
*/
#include "S_Object.h"
#include <string.h>
S_Object::S_Object(){}

void S_Object::netPack (void* addr,int n,char*buff,int counter)
{
     memcpy (&buff[counter],addr,n);
     
}
void S_Object::netRead (void* addr,int n,char*buff,int counter)
{
     memcpy (addr,&buff[counter],n);
     
}
int S_Object::getID()
{
    return ID;
}

Warrior.h (Warrior is a type of object stored in a list) :

#ifndef WARRIOR_H
#define WARRIOR_H

#include "S_Object.h"
class Warrior:public S_Object
{
      public:
             Warrior ();
             int ownerID;
            
             bool isAlive;
             int color;
             
             
             //Client functions
              virtual void update();
             virtual int netUpdate(char*);
            // void netPack(void*,int,char*,int);

             //Server
             virtual void Supdate();
             virtual int pack(char*);//pack hele object
             //void netRead(void*,int,char*,int);
          
      private:
              float xspd,yspd;
              
};
#endif

And finally, Warrior.cpp

#include "Warrior.h"
#include "S_Object.h"
#include <string.h>

Warrior::Warrior()
{
   isAlive = false;
   next = NULL;
}

void Warrior::update()
{
     xpos+=xspd;
     ypos+=yspd;
}
void Warrior::Supdate()
{ 
     xpos+=xspd;
     ypos+=yspd;
}

int Warrior::pack(char*buffer)
{
    int counter = 0;
    netPack(&ID,sizeof(int),buffer,counter);
    counter+= sizeof(int);
    netPack(&xpos,sizeof(float),buffer,counter);
    counter+= sizeof(float);
    netPack(&ypos,sizeof(float),buffer,counter);
    counter+= sizeof(float);
    netPack(&xspd,sizeof(float),buffer,counter);
    counter+= sizeof(float);
    netPack(&yspd,sizeof(float),buffer,counter);
    counter+= sizeof(float);
    netPack(&dir,sizeof(int),buffer,counter);
    counter+= sizeof(int);
    return counter;
}
int Warrior::netUpdate(char* buffer)
{
    //   Kyk hierbo, dieselfde in reverse
    
    int counter = 0;
    netRead(&ID,sizeof(int),buffer,counter);
    counter+= sizeof(int);
    netRead(&xpos,sizeof(float),buffer,counter);
    counter+= sizeof(float);
    netRead(&ypos,sizeof(float),buffer,counter);
    counter+= sizeof(float);
    netRead(&xspd,sizeof(float),buffer,counter);
    counter+= sizeof(float);
    netRead(&yspd,sizeof(float),buffer,counter);
    counter+= sizeof(float);
    netRead(&dir,sizeof(int),buffer,counter);
    counter+= sizeof(int);
    return counter;
}

Any ideas would be appreciated. Unless I'm making some silly syntax error (which im 90% sure is the problem, though i can't find it), I don't see anything wrong here.
rip-off
rip-off
many of you virtual methods have no implementation. if you wnat to use them like so, add an = 0 after them, like so

virtual void someMethod() = 0;

otherwise give them an empty implementation.

that should fix it...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.