2017-02-14 8 views
1

これは非常に簡単な質問です。私が実装して、クラスチェックインコンストラクタ対セット機能

class A 
{ 
public: 
    A(int); 
    void setA(int); 
private: 
    int a; 
}; 

があるとし

A::A(int a_) : a(a_) { } 
void A::setA(int a_) { a = a_; } 

、私はちょうどa = 1で有効なオブジェクトを維持したいのは、私がa = 0を持つ避けたいと言うが、私は例外をスローする必要はありませんしましょうその場合は代わりに(それは今のところ問題ではありません)。

次に、ifステートメントをコンストラクタに追加してsetAに追加して、パラメータが0かどうかを確認し、その場合は1に設定できます。概念的には、この場合、コンストラクタを変更する必要があり、aを初期化する代わりに、setAをコンストラクタに呼び出す必要があることがわかります。このようにして、チェックのコードは1回だけ書き込まれます(これは単純な状況ですが、他の状況では検証がより複雑になる可能性があることに注意してください)。

このアプローチでは、コンストラクタで余分な関数呼び出しを行う必要があります。検証コードを2回書く方が効率的ですか? setAが散発的にしか使用されない場合はどうですか?

+2

とにかくインライン化され、 'setA'でそれを追加し、コンストラクタで' setA'を呼び出します。これらについて心配するのをやめてください(実際にはそうではないようですが)パフォーマンスの違い。きれいなコードを書く。オプティマイザが残りの作業を行います。 –

+1

パラメータの名前を変更する必要はありません。 'A :: A(int a):a(a){}'は問題ありません。 – nwp

+0

@nwpうわー、私はそれを知らなかった。私はこれがいつ行われたかを知るために、言語弁護士の質問をするつもりでしたが、明らかにこれはしばらくの間のことでした:http://stackoverflow.com/q/6185020/2642059 –

答えて

1

私は、コードの重複を防ぐために熱心に同意します。船外に行くことに注意するだけで、1ライナーが船外に出る可能性があります。

あなたが実装ファイル機能やprivateを使用する必要がありますけれども、これを行うにstatic方法チェックをやろうとしている場合は、次のように

int preventZero(const int a_) { return a_ == 0 ? 1 : a_; } 

次に、あなたがあなたの実装でそれを使用することができた:

A::A(int a_) : a(preventZero(a_)) { } 
void A::setA(int a_) { a = preventZero(a_); } 
1

コードの重複が悪いので、コンストラクタでの検証でsetterを呼び出す方がよいでしょう。 CPUサイクルを無駄にしないようにインライン化することもできますが、これは時期尚早の最適化です。

+1

現代のコンパイラは 'inline'を聞きません。 –

+0

AFAIKを強制的にインライン展開するためのコンパイラ固有の属性があります。VSの場合は__forceinlineのようになります。 – dmsovetov

+0

@GillBatesあなたのコードを移植性のないものにする以外に、 '__forceinline'はコンパイラに無視してあなたの判断を良くさせます。このような '__forceinline'の使用はお控えください。 –

関連する問題