5
class T
{};

class AccessT
{
public:
    boost::shared_ptr<const T> getT() const {return m_T;}
    boost::shared_ptr<T>       getT()       {return m_T;}

private:
    boost::shared_ptr<T> m_T;
};

質問> レガシー プロジェクトで上記のようなコードをたくさん見ました。私は本当にそうする意味を理解していません。代わりに、単に以下を提供するだけではどうですか:

class T
{};

class AccessTModified
{
public:
    boost::shared_ptr<T> getT() const { return m_T; }

private:
    boost::shared_ptr<T> m_T;
};

最初の引数はboost::shared_ptr<const T> getT() const、 const オブジェクトが誤って T を変更できないようにすることです。その場合、そのような関数はすべて 2 つのバージョンを提供する必要がありますか? 私にとって、私はとても退屈に感じます!

4

2 に答える 2

9

正解です。目的は、オブジェクトが誤ってTを変更できないようboost::shared_ptr<const T> getT() constにすることです。const

C ++では、これはconstの正当性として知られており、通常は優れたC++設計と見なされます。あなたが言ったように、それはしばしばゲッターが2つのバージョン(aconstと非constバージョン)を持つ結果になります。最初は面倒ですが(慣れれば悪くはありませんが)、結果は非常に役立ちます。定数の正当性により、次のような関数を宣言できます

void DoSomething(const AccessT& item);

これは、変更しないことを約束しているため、変更の可能性があると宣言されていることitemを実行すると、コンパイラはエラーをスローします。DoSomethingitem

constの正当性は通常、優れたC ++設計と見なされますが、一部の開発者は、一部の関数のconstバージョンとnon-constバージョンを宣言する必要があるというオーバーヘッドが価値以上に厄介であると判断しています。

詳細については、 C++FAQに定数の正確性に関するセクション全体があります。

于 2013-02-14T17:44:09.137 に答える
1

このパターンは、アクセサークラスの必要性が感じられる場合に一般的ですが、作成者は、アクセスと常時アクセスの定義AccessTと完全な方法を実行することを望んでいません。AccessTconstあなたが見るハックは、一定および非一定のアクセサーを介して一定および非一定のアクセスを可能にする、それほど面倒な方法ではありません。

このパターンの利点は実装が簡単なことですが、欠点は「constポインター」と「pointertoconst」の概念が混ざり合っていることです。AccessTがsetTメンバーを提供する場合、恒常性についての混乱が生じます。

このアクセスパターンを、const_たとえばイテレータによって示されるパターンと対比することができます。イテレータは、変更可能なイテレータと変更可能なイテレータの4つの組み合わせすべてを許可しますconst_iteratoriterator

于 2013-02-14T17:44:42.730 に答える