4

私はレイトレーシングタスクに取り組んでいます。問題のあるソースは次のとおりです。

class Geometry
{
    public:
        virtual RayTask *intersectionTest(const Ray &ray) = 0;
};

class Sphere : public Geometry
{
    public:
        RayTask *intersectionTest(const Ray &ray);
};

class BoundingVolume
{
    public:
        virtual bool intersectionTest(const Ray &ray) = 0;
};

class BoundingSphere : public Sphere, BoundingVolume
{
    public:
        bool intersectionTest(const Ray &ray) // I want this to be inherited from BoundingVolume
        {
            return Sphere::intersectionTest(ray) != NULL; // use method in Sphere
        }
};

上記のソースはコンパイルできません、エラー情報:

error: conflicting return type specified for ‘virtual bool BoundingSphere::intersectionTest(const Ray&)’
error:   overriding ‘virtual RayTask Sphere::intersectionTest(const Ray&)

Sphereのメソッドを使用してBoundingSphere::intersectionTestを実装したいので、BoundingVolumeとSphereの両方から継承する必要があります。しかし、リターンタイプが異なる同じパラメータリストを持つ関数を継承するため、物事が混乱しました...

同じ機能のコードを複製したくない...誰かが私に解決策を教えてもらえますか?...

4

1 に答える 1

1

コンパイラーは、戻り値のタイプが異なる2つの仮想メソッドをオーバーライドしようとしていますが、これは許可されていません。コンパイラーは、戻り値のタイプがわからない場合、関数呼び出しに割り当てるメモリの量をどのように知るのでしょうか。2つのメソッドに同じ名前を付けることはできません。1つをより適切な意味に変更してみてください。

これらの名前が両方が提供するアクションの意味を最もよく表していると思われる場合(私にはわかりませんが)、階層を慎重に検討することもお勧めします。球形BoundingVolumeは本当にSphere?おそらくそうではありません:それはSphere(プライベート継承、あなたの問題を解決しない)の観点から実装されているか、Sphere(構成、この単純なケースであなたの問題を解決するでしょう)を持っています。BoundingSphereただし、後者の場合は、のすべてのメソッドを使用する必要がある複雑なクラスの移動で問題が発生する可能性がありますSphereBoundingVolumesまたは、おそらく、通常のとを区別する必要がありますGeometryか?

この問題の別の解決策は、これらの階層の1つに非メンバー関数を使用し、ケーニッヒルックアップ(引数のタイプ)が適切なバージョンを呼び出すことです。あなたの階層がどのように見えるかを本当に知らなければ、私は言うことができません。しかし、設計を考慮してください。同じ名前の操作で完全に異なるセマンティック結果が返される場合、その操作は適切に名前が付けられ/設計されていますか?

于 2012-04-29T18:42:18.657 に答える