【发布时间】:2020-12-11 09:29:24
【问题描述】:
在构建我的 C++ 程序时,我收到了错误消息。
对 vtable 的未定义引用
我有两个虚拟抽象类被调用,如果我做错了什么,我无法弄清楚我做错了什么。 我从从抽象类继承的两个类中都收到错误。 我的抽象类是
对 `vtable for hittable_list' 的未定义引用
对 `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
继承自我的抽象类的类是。
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;
}
【问题讨论】:
-
我从来没有想过要制作一个纯虚拟析构函数。想知道会发生什么,它是相关的。
-
是的,就是这样。让我把代码缩小到 minimal reproducible example 并写下来。
-
呵呵。无法重现未定义的
vtable -
这能回答你的问题吗? Undefined reference to vtable,特别是提到检查链接命令的答案。
-
@JaMiT 会这样做,但主要是偶然的。这里的关键是
hittable必须定义析构函数来解决这段代码的所有问题。它可以保持纯粹的virtual,但它必须被定义。从它派生的类必须有可调用的东西。
标签: c++ inheritance polymorphism abstract-class