2009-05-22 23 views
1

constメンバ関数の戻り値がconstであるべきかどうかについては、どのような経験則が良いでしょうか?ここで私がする傾向があるが、私は あいまいなシナリオと闘う。 1つの注意があなたが非対称のconst性を持っていたら、あなたは オブジェクトAを返すために、オブジェクトBを尋ね、その後、オブジェクトBを返すためにconstオブジェクトのAを求めることができる、と は、あなたが意図を回避するために管理してきたということですconstメンバ関数から返されるオブジェクトの定数

class foo 
{ 
    public: 
     // if the returned object is conceptually 
     // (and therefore usually literally but not even necessarily) 
     // owned by *this*, 
     // then a const ptr should be returned 
     const ownedByFoo *getOwnedByFoo() const { return m_ownedByFoo; } 
     ownedByFoo *getOwnedByFoo() { return m_ownedByFoo; } 

     // what's a poor boy to do here? 
     // veryRelatedToFoo might be a conceptual contemporary or parent 
     // of Foo. Note naming the function "find..." instead of "get.." 
     // since *get* implies the object holds it as a data member but 
     // that may not even be the case here. There could be a 
     // standalone container that associates foo and veryRelatedToFoo. 
     // Should constness be symmetrical here? 
     const veryRelatedToFoo *findVeryRelatedToFoo() const; 
     veryRelatedToFoo *findVeryRelatedToFoo(); 

     // If the returned object is only (conceptually) 
     // peripherally related to *this*, 
     // the returned object probably shoudn't be const, even if 
     // foo happens to have one of these as a direct data member, 
     // since we don't want to give away the implementation details of 
     // Foo and it may hold peripherallyRelatedToFoo simply for performance 
     // reasons, etc. 
     peripherallyRelatedToFoo *findPeripherallyRelatedToFoo() const 

    ... 
}; 

オブジェクトのconstity。

答えて

1

何かのconstancesは、あなたが多くの言語で見つける以上のものです!

「物理的にconst」と「論理的にconst」の違いを理解していれば、「あいまいな」シナリオはそのままです:議論の対象です。たとえば、mutableというキーワードが存在する場合でも考慮してください。

私はあなたが右の一般的な考えを持っていると思う:それを超えて、それはすべての議論の余地と主観的だと異なり、特定の問題と制約に従ってなど

私は「ルールには例外」を好むしない傾向にあるので、私constメソッドから非constのポインタを返すのを避ける。私は誘惑されるかもしれないいくつかのシナリオを想像することができると思いますが、代わりにメソッドを非constにすることを決定する可能性が高くなります。

1

- そこ

(私はあなたがそれをカプセル化を壊すので、通常は悪い考えです直接そのようなオブジェクトの状態を、戻ってきているという事実を無視してよ、私は、「サンプルコード」としてこれを探しています)両者の間には関係がありません。 A constメンバ関数は、「実行中」の基底オブジェクトを変更しないメンバです。戻り値がconstであるかどうかの約束または要件はありません。メソッドが返されると、const -ness契約は「オーバー」になります。戻り値とそれを生成したメソッドを接続しようとしているので、混乱していると思います。

戻り値がconstであるかどうかは、戻り値の性質とメソッドに帰属させる意味にのみ依存します。

具体的な最初のケースでは、2つのメソッドは同じconst -nessを返す必要があります。 constのオーバーロードはおそらくあなたが使いたいものではありません。あなたは2つのバリエーションが必要な場合、私はおそらく、このようなように、それが明示的になるだろう:

const ownedByFoo *getOwnedByFoo() const { return m_ownedByFoo; } 
ownedByFoo *getOwnedByFooForEdit() { return m_ownedByFoo; } 

その方法をあいまいと2の無い謎の抱き合わせはありません。クライアントコードがconstオブジェクトのm_ownedByFooを変更しないようにするため、2番目の非constを作成したことに注意してください。これは、メソッドの意味(「内部状態を返す」)から生まれたものであり、メソッドのconst -nessと返り値のconstの間のリンケージからではありません。返される値がオブジェクトの状態の一部でない場合、私はおそらく他の何かをするでしょう。

+1

技術的には、あなたはconst-ness契約で正しいですが、それは過度にリテラルな解釈です。オブジェクトを無邪気に(constのように)自分自身の部分を渡すように要求し、非constオブジェクトを(あなたの心臓のコンテンツに変更することができますか?)その方法はあなたのオブジェクトにトロイの木馬です。 あなたの2番目のポイントは良いです。私は人々が一般的にはオーバーロードされた署名に慣れていると思います。なぜなら、constや非constの状況では、どこでも同じgetメソッドを使用することができるからです。呼び出し元に考えることはしばしば良いことです。 –

+0

@私は同意し、文字通りの解釈が混乱を避けることが分かりました。あなたが "銃を装備して"提供することで、あなたがその罠に入ったという議論が始まります(州の非constへのポインタ)。私は次のいずれかを提案するかもしれません:a)常にconst *を返すことを考えてください(あなたのセマンティクスを作ります)。 b)実際の状態のコピーを提供することを検討する。セマンティクスでそれを指定し、対応するコピーコストを支払う。 c)constオーバーロードをプライベートにすることを検討して、メソッドをconstオブジェクトに対して呼び出すことはできません。 –

+0

...私は個人的には、あなたのオブジェクトのconst'nessに依存する戻り値のconst'nessについてあまりにもあいまいであることがわかります。 YMMV。 –

0

constメソッドからメンバーデータへの非constポインタまたは参照を返しません。

0

返される参照がconstの場合は、関数constを作成します(存在しない場合)。クラスが主に何らかのコンテナクラスでない限り、カプセル化を破るので、メンバデータへの非const参照を返さないようにする必要があります。

0

非const参照/ポインタを返すと、呼び出し元はクラスが保持しているべき不変条件を無効にできます。その場合、非const参照/ポインタを返さないでください。 (それはconstでなければなりません)

関連する問題