2016-11-06 23 views
1

私は抽象度がclass AbstractClassです。すべての派生クラスにはconst std::vectorがあるはずですが、このフィールドは派生クラスclass(型付き)に関連付けられています。インスタンスではありません。したがって、それをstaticとすることは素晴らしいことです。もちろん、私はそれを基底クラスで定義することはできません。将来的に追加できる派生クラスごとにこれを実装することはできません。純粋仮想メソッドがconst参照を返す

新しい派生クラスを定義する誰かがstaticとして実装することを願っています。 (そうでなければ、プログラムは正常に動作するはずですが、不要なメモリ占有があります....)。

だから私は、この変数を返す純粋vitual方法があります:私は、派生クラスの存在

virtual const std::vector<SomeType>& getVec() const = 0; 

は次のように定義されています

class DerivedClass : public AbstractClass 
{ 
public: 
    const std::vector<SomeType>& getVec() const { return vec; } 
private: 
    static const std::vector<SomeType> Vec; 
} 

私はこれが安全やろうと、私は他のその可能性を考えますプログラマは新しい派生クラスを追加し、別の方法で実装することができます。 例:

const std::vector<SomeType>& getVec() const { return std::vector<SomeType>{ arg1, arg2}; } 

私はコピーを避けたいので返された型をconst referenceと定義しました(Vecがクラスのメンバーの場合)...このメソッドを公開するのは大丈夫ですか安全ですか?返品に危険がありますかconst reference

+6

スタック変数へのポインタ/参照を返すことは、単独のバグです。 IMO、それはインターフェイスを設計することとは関係ありません。 – erenon

+0

クラスは、a)データと、b)データを使用するコードとをグループ化するために使用されます。 'getters'は設計上の誤りの明確な証拠です...自分自身に尋ねます。なぜこれらの派生クラスのベクトルがありますか?そのベクトルを使っているコードはどこかにありますか?データ? –

+0

Martin Fowlerの "TellDontAsk"も参照してください(この場合、Derivedクラスに...) –

答えて

1

目的の動作を実装するCRTPを使用して、継承する別のインターフェイスを提供することによって、デザインを強化することができます。それぞれのクラスに静的なstd::vectorが必要ですか?あなたは次の操作を行います。

class AbstractClass 
{ 
    template<typename> 
    friend class DerivedBase; 

    AbstractClass() = default; 

    public: 
    virtual const std::vector<SomeType>& getVec() const = 0; 
}; 

template<typename CRTP> 
class DerivedBase : AbstractClass 
{ 
    protected: 
    DerivedBase() = default; 
    static const std::vector<SomeType> vec; 

    public: 
    const std::vector<SomeType>& getVec() const { return vec; } 
}; 

class DerivedClass : DerivedBase<DerivedClass> 
{ 
}; 

は今、各DerivedClassは-あるこのデザインを強制仲介経由AbstractClass。 CRTPのおかげで、それぞれDerivedClassは自動的に独自の静的ベクトルを取得します。


[1] Iは、コードショートを維持するために、そのような仮想デストラクタとして、正確さに関連する重要な詳細を省略する。それらについて忘れないでください。

3

この方法を公開するのは大丈夫ですか安全ですか?

はい、そうです。

戻り値const referenceには危険がありますか?

いいえありません。


別の開発者は、あなたが示してきた方法で、インタフェースを実装している場合、彼らは自分のコードでは、未定義の動作になってしまいますし、遅かれ早かれ、それは失敗します。

他の人があなたのインターフェイスを使用して間違って実装することを防ぐ言語機能はありません。

0

メンバ関数の呼び出し元がルールに従って動作する場合、この関数を作成する上で、まったく危険はありませんpublic

ベクトルがconst_castであり、それを修正する可能性もあります。ユーザーを信頼しない場合は、コピーに切り替える必要があります。

関連する問題