C++ 未定义对vtable的引用,并实现了所有虚拟函数

C++ 未定义对vtable的引用,并实现了所有虚拟函数,c++,C++,我定义了这两个结构: #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

我定义了这两个结构:

#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_ */

但是,当我尝试编译时,会出现以下两个错误:

undefined reference to `vtable for object'
我知道它不是我的makefile,因为它已经添加了sphere.cpp和object.cpp 我的结构中是否缺少导致这种情况的函数或方法

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;
}
出现此错误是因为尚未在对象中提供虚拟方法的定义<代码>基本上vtable存储函数指针,即需要虚拟函数的地址。所以,如果您错过了单个虚函数的定义,编译器将无法为该类生成完整的vtable

对于您的对象类
vtable
将类似于:-

&object::intersect
&object::normal
编辑:-

这意味着对应于这些:-

virtual float intersect(Point, Vector, object*, Point*);
virtual Vector normal(Point, object*);
你应该有:

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

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

如果没有对象::intersect和对象::normal的定义,则应将其设置为纯虚拟函数,如下所示:

#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_ */
\ifndef OBJECT\u
#定义对象_
#包括
#包括“vector.h”
结构对象{
公众:
int index;//标识对象;必须大于0
float mat_ambient[3];//Phong模型中使用的材质属性
浮动垫扩散[3];
浮垫镜面反射[3];
浮垫光亮度;
浮点反射率;//此数字[0,1]确定反射光对像素颜色的贡献程度
虚拟浮点相交(点、向量、对象*、点*)=0;
虚拟向量法线(点,对象*)=0;
};
#endif/*对象*/

试试看,我想它会解决你的问题。

可能重复吗?我看到了那个,并尝试了他建议的一切,但我还是很奇怪,你能包括Makefile吗?你没有“定义所有虚拟函数”<代码>对象::intersect是一个不存在的对象。了解纯虚拟函数。然后想知道为什么不能实例化抽象类。另外,使用-Wall-Weffc++编译并使用零警告抱歉,请划掉抽象类位。您能详细说明我应该提供什么定义吗?因此,如果我有一个
向量
,并将一个球体存储到该向量中。然后在向量中迭代,会调用什么函数?object.normal或sphere.normal划破这个问题,对于那些想知道的人来说,它确实叫sphere.normal。这是一个漫长的一天,大脑中充满了一种叫做“交集”的功能,实际上它并没有交集功能。。在代码审查时交给您。为什么会有它?如果
对象
是一个抽象类(即从未直接创建),那么OP应该根据windywolf的回答将
对象::intersect()
对象::normal
声明为纯虚拟方法(使用
=0;
)。也许OP可以考虑一下,并决定这个答案是否真的比windywolf的好。
virtual float intersect(Point, Vector, object*, Point*);
virtual Vector normal(Point, object*);
float object::intersect(Point, Vector, object*, Point*)
{
}

Vector object::normal(Point, object*)
{
}
#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_ */