我定义了这两个结构:
#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_ */
然而,当我尝试编译时,我得到了这两个错误:
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;
}
生成文件
#! /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
答案 0 :(得分:3)
undefined reference to `vtable for object'
您收到此错误是因为您未在对象中提供虚拟方法的定义。 Basically vtable stores function pointers
,即虚拟功能的地址是必需的。因此,如果您错过了单个虚函数的定义,编译器将无法为该类生成完整的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*)
{
}
答案 1 :(得分:1)
如果没有对象:: intersect&amp;的定义object :: 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_ */
尝试一下,我认为它可以解决你的问题。