2017-08-11 11 views
1

私はベースクラスShapeを持っていて、仮想関数intersect()を持っています。C++ - エラー:基本クラス仮想関数の不完全型へのメンバアクセス

HitRecordは、同じ.hファイルで定義されている構造体です。

また、Shapeの子クラスはTriangleです。私はShape::intersect()HitRecordのメンバーにアクセスしようとしているが、私はエラーにerror: member access into incomplete type in base class virtual function

を得た私が子供のクラスでこれを行うが、基本クラスにすることはできませんでしたということ奇妙です。

仮想が機能していますか?

注:もう1つ奇妙なことに、私は自分の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

この問題は循環依存として知られています。あなたのコードで

..

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

これはvirtualをマークされている機能とは何の関係もありません。 recの型定義を知らなくても、コンパイラはどのようにrec.objが(そのようなメンバが存在すれば)何を知ることができますか?

HitRecordの定義の後Shape::intersectアウトオブラインを定義します(理想的には、一つのファイルにすべてを入れていない)、またはShape/HitRecord定義と、前方宣言Shapeの順序を入れ替えます。

+0

HitRecord' 'の前方宣言は、このような状況を扱うことができないのはなぜ? 'intersect()'のシグネチャにも 'HitRecord'が含まれていますが、コンパイラはエラーを投げませんか? –

+0

不完全な型のポインタまたは参照を宣言できます。 – LogicStuff

関連する問題