【问题标题】:c++ - error: member access into incomplete type in base class virtual functionc++ - 错误:成员访问基类虚函数中的不完整类型
【发布时间】:2017-08-12 00:52:14
【问题描述】:

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

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

另外,Shape 有一个子类 Triangle。我正在尝试在Shape::intersect() 中访问HitRecord 的成员,但出现错误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;
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    这个问题被称为循环依赖。

    在你的代码中..

    // 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;
     }
    

    【讨论】:

      【解决方案2】:

      这与标记为virtual 的函数无关。编译器如何知道rec.obj 是什么(如果存在这样的成员)而不知道rec 的类型的定义?

      HitRecord 的定义之后定义Shape::intersect 行外(最好不要将所有内容放在一个文件中)或交换Shape/HitRecord 定义的顺序和前向声明@987654328 @。

      【讨论】:

      • 为什么HitRecord的前向声明不能处理这种情况? intersect()的签名也包含HitRecord但是编译器没有报错?
      • 可以声明不完整类型的指针或引用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 1970-01-01
      • 2021-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多