Undefined reference to vtable with all virtual functions implemented

I have these two structures defined:

#ifndef OBJECT_H_
#define OBJECT_H_
#include <stdio.h>
#include "vector.h"

struct object{
public:
    int index;               // identifies a object; must be greater than 0
    float mat_ambient[3];    // material property used in Phong model
    float mat_diffuse[3];
    float mat_specular[3];
    float mat_shineness;
    float reflectance;       // this number [0,1] determines how much
                             // reflected light contributes to the color
                             // of a pixel
    virtual float intersect(Point, Vector, object*, Point*);
    virtual Vector normal(Point, object*);
};
#endif /* OBJECT_H_ */

      


#ifndef SPHERE_H_
#define SPHERE_H_

#include "object.h"

struct sphere: public object {
public:
    Point center;
    float radius;

    // intersect ray with sphere
    float intersect(Point, Vector, object*, Point*);
    // return the unit normal at a point on sphere
    Vector normal(Point, object*);
};
#endif /* SPHERE_H_ */

      


However, when I try to compile, I get the following two errors:

undefined reference to `vtable for object'

      

I know this is not my makefile since it has already added sphere.cpp and object.cpp Is there a function or method missing from my structures that is calling this?

object.cpp

#include "object.h"

#include <stdlib.h>
#include <math.h>
#include <iostream>
#include "sphere.h"

using namespace std;

/**********************************************************************
 * This function intersects a ray with a given sphere 'sph'. You should
 * use the parametric representation of a line and do the intersection.
 * The function should return the parameter value for the intersection,
 * which will be compared with others to determine which intersection
 * is closest. The value -1.0 is returned if there is no intersection
 *
 * If there is an intersection, the point of intersection should be
 * stored in the "hit" variable
 **********************************************************************/
float sphere::intersect(Point A, Vector p, object *o, Point *hit) {
    cout << "intersect" << endl;
    sphere* s = (sphere*) o;
    Point C = s->center;
    Point B;
    B.x = A.x + p.x;
    B.y = A.y + p.y;
    B.z = A.z + p.z;

    float a = pow(B.x - A.x, 2) + pow(B.y - A.y, 2) + pow(B.z - A.z, 2);
    float b = 2 * ((B.x - A.x) * (A.x - C.x) + (B.y - A.y) * (A.y - C.y) + (B.z - A.z) * (A.z - C.z));
    float c = pow(A.x - C.x, 2) + pow(A.y - C.y, 2) + pow(A.z - C.z, 2) - pow(s->radius, 2);

    float delta = pow(b, 2) - 4 * a * c;

    if (delta < 0.0) {
        //no intersection
        return -1.0;
    }
    if (delta >= 0.0) {
        //possibly more then one intersection, but at least one, return the smallest one
        float d1 = (-b - sqrt(delta)) / (2 * a);
        float d2 = (-b + sqrt(delta)) / (2 * a);
        if (d1 < d2) {
            hit->x = A.x + (p.x * d1);
            hit->y = A.y + (p.y * d1);
            hit->z = A.z + (p.z * d1);
            return d1;
        } else {
            hit->x = A.x + (p.x * d2);
            hit->y = A.y + (p.y * d2);
            hit->z = A.z + (p.z * d2);
            return d2;
        }
    }
    return -1.0;
}
/******************************************
 * computes a sphere normal - done for you
 ******************************************/
Vector sphere::normal(Point q, object *o) {
    sphere *sph =  (sphere *) o;
    Vector rc;

    rc = get_vec(sph->center, q);
    normalize(&rc);
    return rc;
}

      

Makefile

#! /usr/bin/make

SOURCE= scene.cpp image_util.cpp sphere.cpp vector.cpp trace.cpp raycast.cpp object.cpp include/InitShader.cpp

CC= g++

CFLAGS= -O3 -ggdb -O0  -Wall -pedantic -DGL_GLEXT_PROTOTYPES -std=c++11

EXECUTABLE= raycast

LDFLAGS = -lGL -lglut -lGLEW -lXext -lX11 -lm

INCLUDEFLAG= -I. -I$(INCLUDEDIR) -Iinclude/
LIBFLAG= -L$(LIBDIR)

OBJECT= $(SOURCE:.cpp=.o)

all: $(OBJECT) depend
    $(CC) $(CFLAGS) $(INCLUDEFLAG) $(LIBFLAG)  $(OBJECT) -o $(EXECUTABLE) $(LDFLAGS)

depend:
    $(CC) -M $(SOURCE) > depend

$(OBJECT):
    $(CC) $(CFLAGS) $(INCLUDEFLAG) -c -o $@ $(@:.o=.cpp)

clean_object:
    rm -f $(OBJECT)

clean:
    rm -f $(OBJECT) depend $(EXECUTABLE)

include depend

      

+3


source to share


2 answers


undefined reference to `vtable for object'

      

You are getting this error because you did not specify a virtual method definition in the object. Basically vtable stores function pointers

Requires virtual function address. Therefore, if you missed the definition of a single virtual function, the compiler will not be able to create a complete vtable for that class.

For your object class, it vtable

will be something like: -

&object::intersect
&object::normal

      

EDIT: -



This means the following: -

virtual float intersect(Point, Vector, object*, Point*);
virtual Vector normal(Point, object*);

      

You must have: -

float object::intersect(Point, Vector, object*, Point*)
{
}

Vector object::normal(Point, object*)
{
}

      

+3


source


If there is no definition for object :: intersect and object :: normal, you should make them pure virtual functions as shown below:

#ifndef OBJECT_H_      
#define OBJECT_H_
#include <stdio.h>
#include "vector.h"

struct object{
public:
    int index;               // identifies a object; must be greater than 0
    float mat_ambient[3];    // material property used in Phong model
    float mat_diffuse[3];
    float mat_specular[3];
    float mat_shineness;
    float reflectance;       // this number [0,1] determines how much reflected light contributes to the color of a pixel
    virtual float intersect(Point, Vector, object*, Point*) = 0;
    virtual Vector normal(Point, object*) = 0;
};
#endif /* OBJECT_H_ */

      



Try it and I think this will figure out your problem.

+1


source







All Articles