c ++ - 错误:成员访问基类虚函数中的不完整类型

时间:2017-08-11 16:42:23

标签: c++

我有一个基类Shape,它有一个虚函数intersect()

HitRecord是在同一.h文件中定义的结构。

此外,Shape还有一个子类Triangle。我试图访问HitRecordShape::intersect()的成员,但收到错误error: member access into incomplete type in base class virtual function

奇怪的是,我可以在子类中执行此操作,但不能在基类中执行此操作。

是否因为它是虚拟功能?

注意:另一个奇怪的事情:我可以在我的Ubuntu 16.04上运行,但在我的Mac上遇到此错误。

struct HitRecord;   // forward declaration

class Shape {
public:
    virtual bool intersect(Ray& r, HitRecord& rec) {
        std::cout << "Child intersect() is not implement." << std::endl;
        rec.obj = this;
        return false;
    }
}

struct HitRecord {
    float t;
    vec3f p;    // point coord
    vec3f norm;
    Shape* obj;
};

class Triangle: public Shape {
public:
    Mesh* mesh_ptr;
    unsigned int vertexIndex[3];

    Triangle() {...}

    Triangle(Mesh* m) {...}

    inline bool intersect(Ray& r, HitRecord& rec);
}

inline bool Triangle::intersect(Ray& r, HitRecord& rec) {
    vec3f n = cross(v1-v0, v2-v0);
    float t = - (dot(n, r.origin())+d) / dot(n, r.direction());
    vec3f p = r.origin() + t*r.direction();

    rec.t = t;
    rec.p = p;
    rec.norm = unit(n);
    rec.obj = this;
    return true;
}

2 个答案:

答案 0 :(得分:2)

此问题称为循环依赖。

在您的代码中..

// in shape.h

struct HitRecord;   // forward declaration

                    // this forward declaration means all you can do until 
                    // the struct is fully declared is declare a pointer
                    // or a reference to it.  No more.

class Shape {
public:
    virtual bool intersect(Ray& r, HitRecord& rec);  // <-- this is fine


    virtual bool intersect(Ray& r, HitRecord& rec) {
        //...
        rec.obj = this;   // <-- this is where you hit an error. the compiler
                          // doesn't know yet what HitRecord::obj is.
        return false;
    }
};


.. in hitrecord.h...

struct HitRecord {
    float t;
    vec3f p;    // point coord
    vec3f norm;
    Shape* obj;
};


 // this would usually reside in shape.cpp, but what's important is the order
 // in which the compiler reads the successive declarations

 #include "shape.h"
 #include "hitrecord.h"   // for example...

 bool Shape::intersect(Ray& r, HitRecord& rec) 
 {
 //...
     rec.obj = this;   // Now, the compiler knwos all about HitRecord
                       // so this will compile.
     return false;
 }

答案 1 :(得分:1)

这与被标记为虚拟的功能无关。如何在不知道rec类型定义的情况下,编译器如何知道rec.obj是什么(如果这样的成员存在)? 在定义HitRecord之后定义Shape :: intersect out-of-line(理想情况下不要将所有内容放在一个文件中)或交换Shape / HitRecord定义和forward-declare Shape的顺序。