When building my C++ program, I'm getting the error message.
undefined reference to vtable
I have two virtual abstract classes called and I can't quite figure out what I'm doing wrong if I'm doing anything wrong. I'm getting errors from both of the classes that are inheriting from the abstract class. My abstract class is
undefined reference to `vtable for hittable_list'
undefined reference to `vtable for sphere'
hittable.h
#ifndef HITTABLE_H
#define HITTABLE_H
#include "ray.h"
struct hit_record {
hit_record() {}
~hit_record() {}
float t;
vecfloat p;
vecfloat normal;
float MAXFLOAT = 100.0;
};
//Abstract Class containing Sphere and hittablelist
class hittable
{
public:
virtual ~hittable() = 0;
virtual bool hit(const ray &r, float t_min, float t_max, hit_record &rec) const = 0;
};
#endif
Classes inherting from my abstract class are.
sphere.h
#ifndef SPHERE_H
#define SPHERE_H
#include "hittable.h"
class sphere : public hittable
{
public:
sphere() {}
~sphere() {}
sphere(vecfloat cen, float r) : center(cen), radius(r) {}
bool hit(const ray &r, float t_min, float t_max, hit_record &rec) const;
protected:
vecfloat center;
float radius;
};
#endif
sphere.cc
#include "include/sphere.h"
bool sphere::hit(const ray &r, float t_min, float t_max, hit_record &rec) const
{
vecfloat oc = r.origin() - center;
float a = oc.dot_product(r.direction());
float b = oc.dot_product(oc) - radius * radius;
float c = oc.dot_product(oc) - radius * radius;
float discriminant = b * b - a * c;
if (discriminant > 0)
{
float temp = (-b - sqrt(b * b - a * c)) / a;
if (temp < t_max && temp > t_min)
{
rec.t = temp;
rec.p = r.point_at_parameter(rec.t);
rec.normal = (rec.p - center) / radius;
return true;
}
temp = (-b + sqrt(b * b - a * c)) / a;
if (temp < t_max && temp > t_min)
{
rec.t = temp;
rec.p = r.point_at_parameter(rec.t);
rec.normal = (rec.p - center) / radius;
return true;
}
}
return false;
}
hittable.h
#ifndef HITTABLELIST_H
#define HITTABLELIST_H
#include "hittable.h"
class hittable_list : public hittable
{
public:
hittable_list() {}
hittable_list(hittable **l, int n)
{
list = l;
list_size = n;
}
bool hit(const ray &r, float t_min, float t_max, hit_record &rec) const;
~hittable_list() {}
protected:
hittable **list;
int list_size;
};
#endif
hittable.cc
#include "include/hittablelist.h"
bool hittable_list::hit(const ray &r, float t_min, float t_max, hit_record &rec) const
{
hit_record temp_rec;
auto hit_anything = false;
auto closet_so_far = t_max;
for (int i = 0; i < list_size; i++)
{
if (list[i]->hit(r, t_min, closet_so_far, temp_rec))
{
hit_anything = true;
closet_so_far = temp_rec.t;
rec = temp_rec;
}
}
return hit_anything;
}