2011-07-19 15 views
4

私は、ポインタを返す関数がconstではない理由があるかどうかを知りたかったのです。私はほとんどの場所でconst正しいと思われるいくつかのコードに取り組んでいますが、何らかの理由でconstとしてポインタを返す関数を宣言していません。例えば、それは実際にgetJointByID機能自体は、クラスの任意のメンバーを変更しない場合は、constのはすべきではない何らかの理由がある?C++:ポインタを返す関数がconstではない理由は何ですか?

virtual Joint* getJointByID(unsigned int id); 

代わりの

virtual Joint* getJointByID(unsigned int id) const; 

を書き込み

+2

ポインタを介してオブジェクトの状態を変更することはできますか? –

+0

返されたポインタを使って、yesを返しますが、関数呼び出し自体はクラスのデータメンバーを変更しません。 – Gravity

答えて

7

これは実際に意味があります。関数がconstと宣言されている場合、それは定数インスタンス(constvar.getJointByID ...)で使用できることを意味します。しかし、変更可能な内部構造体へのポインタを返すと、ユーザーはインスタンスのconst制限をバイパスできます。

constと同じように宣言されていないときは、constインスタンスで関数を呼び出すことができないため、constnessが保持されます。 constと宣言された場合は、const Joint*が返されたほうがよいでしょう。

(ここでは、ジョイント*が実際にクラスデータ構造の一部であると仮定しています。クラスが新しく割り当てられたコピーの一部を返した場合、それは定数ではありません。実装)

+0

+ 1.コードがこのように設計された理由の非常に良い説明。そして、はい、ジョイントはクラスデータの一部であり、参照渡しされます。 – Gravity

1

私は、 ポインタを返す関数がconstであってはならない理由があるかどうかを知りたいと思っていました。

このような経験則はありません。 constは、関数内で何をしているかによって異なります。

実際にgetJointByID関​​数自体がクラスのメンバー を変更しない場合は、constが存在しない理由はありますか?

ここで正しいです。この関数は良いプログラミング実践の一環としてconstであったはずです。ただし必須ではありません。

また、派生クラスのほとんどは、virtualメソッドをオーバーライドするときに、基本クラスの同じメソッドパターンに従います。さて、基本クラスがレガシーの場合、constを入れて構文を変更することはできません。派生したすべてのクラスに対して同じチェーンが続く。

1

Const精度は戻り値の型だけに依存しません。あなたがこの方法から帰ってくるものも重要です。

オブジェクトの内部データを返す場合、メソッドの修飾子constは、他の人がこの内部データを変更できないようにします。メソッドの中のオブジェクトを変更しなくても、内部を突然変異の許諾を得て外部に提供することはできません。これは、クラスの定数インスタンス化でこのメソッドを呼び出すと意味をなさないものです。

あなたの最善の策は、定数へのポインタでそれを保護することにより、あなたのメンバーデータを返すことです:

virtual const Joint* getJointByID(unsigned int id) const; 
+0

返されたポインタを介してオブジェクトの状態を変更する可能性があります。だから...私はconstとして関数を宣言すべきではないという意味ですか?また、私がconst Joint *を返すと、それはl-valueとして逆参照することはできませんでしたが、依然としてr-valueとして参照解除される可能性があります。または、constはポインターの値にのみ適用され、ポインターのポインターには適用されませんか? – Gravity

+0

@Gravity - 定数メソッドは、定数オブジェクトから呼び出すことができるメソッドです。オブジェクトの内部状態を変更したい場合は、定数オブジェクトにすることはできません。あなたのメソッドを定数として宣言することはできません。 'const Joint *'は定数 'Joint'オブジェクトへのポインタを意味します。これはオブジェクトを指し、ポインターは指しません。しかしどちらの場合でも、戻り値をl値として使用することはできません。戻り値の型としてのプリミティブ型(この場合はポインタ)は、言語設計によって不変です。これはあなたの問題とは無関係の特別なケースです。 –

+0

私はそのようなポインタの逆参照の結果を意味し、ポインタ型自体は意味しません。つまり、私は(*返されたジョイント)=何かができることは事実ですか? returnedJointにconstが設定されていない場合のみ – Gravity

1

戻り値の型とconstの訂正の間には関係ありません。あなたが返すポインタがオブジェクトの一部である構造である場合、あなたはそのポインタを通じてオブジェクトを変更することができるしているのでconstとして関数を宣言constへのポインタを返す、またはべきではありません

しかし

関連する問題