2012-01-14 5 views
0

最近リリースされたDoom 3ソースを見て、C++とOpenGLを強化しようと考えました。これまで多くのことを学んだことがありますが、私は壁に衝突しました。クラス詳細hereメソッドDoom 3 source:なぜ2ベクトルを表すクラスが添え字演算子に2回オーバーロードするのですか?

float operator[] (int index) const 

体の両方 xクラスは、2人のデータメンバーの一つである

return (&x)[ index ]; 

(他方はyことを読み出す

float & operator[] (int index) 

を有し、このクラスは2ベクトル用です)。

各バージョンのヘッダー/プロトタイプの構文を理解することはできますが、なぜそれらが両方とも存在するのかわかりません。

constは、コンパイルを可能にするだけのヘッダーを区別するためにのみ表示されます(または表示されないようにする)。 (つまり、constを取り除き、VS2010は両方のヘッダがconstで終わった場合と同様にコンパイルを拒否します)

なぜrefをfloatに戻すのですか?クラスの7つの他の浮動小数点型のメソッドのどれもこれを行っていないので、私は効率が1つの要素ではないと推測しています(この演算子は他よりも頻繁に呼び出されます)。

ここで何が起こっているかのように任意の洞察力に感謝

...

+0

私は確かに良い答えが得られると確信していますが、最初の方法は、 'const'(つまり、書き込みはしません)というベクトルのメンバーにアクセスできる' const'です。もう1つの方法では、 'const'でないベクトルのメンバーを変更することができます(つまり、参照によって読み書きが可能になります)。 –

+0

[Operator overloading]の重複の可能性があります(http://stackoverflow.com/questions/4421706/operator-overloading) – sbi

答えて

7

これは一般的なイディオムである(「constのオーバーロード」として知られています)。 C++ FAQ:http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.12を参照してください。

*thisconstであるかどうかによって曖昧さが解決されます。 constオブジェクトでは、constオーバーロードが呼び出されます。この場合、読み取り専用スタイルで動作します。非constオブジェクトでは、非constが呼び出されます。この場合、読み取り/書き込みスタイルで動作します。

これは、ではなく、であることに注意してください。読み取りアクセスと書き込みアクセスを区別する方法。

+0

私は突然、この回答を地獄に標準引用するよう促しますが、悲しいかな、説明する賢い方法ですそれは非標準的な話し手に。 :)また、@ケレックは言った。 'this'のCv-qualificationは' X * cv'、 'cv X *'(9.3.2/1参照)です。 – Xeo

+0

興味深いことに、[この回答](http://stackoverflow.com/a/8610728/500104)では、過負荷解決の仕組みの詳細について説明しています。それはかなり複雑なプロセスなので、自分で準備してください。 :)また、 '* this'に関するいくつかのこと、なぜオーバーロードの解決がそれに基づいていないのか(ヒント:' this'は非静的メンバー関数内にのみ存在します) – Xeo

+0

ありがとうOli、Xeo。今、誰がこのKerrekSBですか? – user1148739

0

constを指定しない場合は、関数を呼び出すときに値を変更する必要があるため、参照を使用しています。例えば、値を設定する:a [11] = 5.0;

他の関数がconst関数として宣言できるのは、それらが呼び出す他の関数もconst関数である場合のみです。

0

なぜrefをfloatに戻すのですか?

フロートへの参照を返す理由は、呼び出し元がそのフロートを変更できるようにするためです。 (ポインタがフロートと少なくとも同じ大きさで傾向があるので、余分な間接純粋なコストであるような方法で、効率は、この理由ではない。)メソッドシグネチャの終わりに

constオブジェクト/参照/式constで安全に呼び出すことができることを示します。vidVec2であれば、その後、v[0]は(とv[0] = 3.0fが実際にv[0]を設定します)左辺値として使用することができるが、vconst idVec2であれば、その後、v[0]は唯一(v[0] = 3.0fがilegalであることを意味する)右辺値として使用することができます。 ゲッターセッター添字要素について方法の関連ペアとしてそれらの

1

考えます。 float & operator[](int index)セッターバージョンであり、あなたがそうのような構文を使用することができます:

theObject[anIndex] = 1.0; 

これはtheObjectは、非const対象として(またはObject *またはObject &を通じて)あなたに利用可能であることが必要です。

関連する問題