0

だからここに状況があります:

レイトレーサープログラムの抽象的なスーパークラス「モデル」があり、そこからさまざまな種類のジオメトリがプロパティと関数を継承します。明らかに、タイプモデルのオブジェクトはありませんが、シーンのジオメトリ全体が格納されるタイプモデルの配列があります。

次に、レイトレーサーによって多数のレイがキャストされます。各光線はこのモデルの配列を反復処理し、独自のメソッドRay::intersectを使用してそれらと衝突するかどうかを確認します。したがって、レイの宣言にはおおよそこれが含まれます。

Point intersect(Sphere sphere) {...}

Point intersect(Cube cube) {...}

Point intersect(Torus torus) {...}

問題は、これらのクラスはすべてModelを継承し、配列はmodel型であるため、要素にアクセスするとmodel型になるということです。モデルには交差点がないので、そのような方法がないというエラーほど間違った方法のエラーが発生することはありません。したがって、問題は、各メンバーを適切なタイプにキャストするにはどうすればよいかということです。

これを行うための合理的な方法はありますか、それともオブジェクトごとに各サブクラスを明示的にキャストし、スティックを使用してみる必要がありますか?これは、一般的な問題のように思われることに対して非常にハックのようです。

4

1 に答える 1

1

あなたはそれを逆にすべきです。Ray withPoint intersect(Sphere sphere)などを使用する代わりに、各モデルは次のような関数を使用する必要がありますvirtual Point intersect(const Ray& ray) const

PS。余談ですが、配列がModel *の配列または何らかの形式のスマートポインターであることを確認してください。そうでない場合は、モデルをスライスすることになります。

PPS。実際のレイトレーサーは、レイをまとめてバッチ処理する方法を見つけるため、(仮想)関数呼び出しはそれほど多くありません。

編集:

また、特定のモデルにキャストすることも可能ですが、この場合にそれを使用すると、OOP性が損なわれ、醜いswitchステートメントになります。たとえば、がありModel* model、それがである可能性があると考えた場合、次のSphere*ことができますSphere* sphere = dynamic_cast<Sphere*>(model);modelが実際にだった場合はSphere*、それsphereを指すようになります。そうでない場合は、sphereになりますNULL。IMOはdynamic_cast、ほとんどすべての状況で使用しないようにする必要があります。あなたがそれを使わなければならないことに気付いた場合、それは通常あなたのデザインが台無しにされたことの兆候です(再デザイン、または時間がない場合はあなたの過ちから学びます)。

于 2012-09-19T01:10:52.577 に答える