3

次の定義は悪いスタイルですか、それとも単純に間違っていますか? つまり、正しくないと見なされる値を初期化した後にスローするのは間違っていますか?

myClass::myClass(int arg) : value(arg)
   {
    if (value < 0)
       throw (myException("Negative value not allowed!"));
   }

本体に値を割り当てるよりも intializer-list を使用する方が望ましいと思われます。私が理解していることから、値が割り当てられた後またはにスローするかどうかは問題ではありません。

4

5 に答える 5

5

引数が有効な範囲内にない場合、初期化子リストを使用し、値を初期化する前にスローすることもできる代替手段:

inline int RequirePositive(int value)
{    
    if (value < 0) throw (myException("Negative value not allowed!"));
    return value;
}

class myClass {
    myClass(int arg) : value(RequirePositive(arg)) {}
};
于 2012-11-12T22:42:51.390 に答える
4

>= 0 がクラス不変である場合value、実際にはいくつかの可能性しかありません。1 つは、パラメーターを受け入れるように ctor を作成するunsignedことです。そのため、値 <0 は単純に不可能でした。もう 1 つは、例外をスローすることです。

しかし、はい、有効なオブジェクトを作成できない値をユーザーが渡した場合、例外をスローすることは完全に受け入れられます (通常は正しいことです)。コンストラクターの責任は、有効なオブジェクトを作成することです。有効なオブジェクトを作成できない値が渡された場合、通常は例外が正しい応答です。

いつ例外をスローするかについて: 少なくともこの場合は、それほど重要ではありません。例外は現在のオブジェクトの作成をロールバックするため、とにかく存在しません。値をコピーしてから無効な場合は破棄するよりも、最初に値をテストする方がはるかに高速であれば、違いが生じる可能性があります。そのようなものではint、ほとんど無関係です。たとえば、ある種の大きなツリーがあり、ツリーのルート ノードなどを見るだけでそれが有効かどうかを判断できる場合は、最初にそのノードを調べて、3 つのノードだけをコピーする方がよいでしょう。有効だった場合。

後者は明らかに最適化ですが、プロファイリングを行わなくても価値があるほど十分に大きくシンプルなものになる可能性があります (おそらく、ペシミゼーションを回避するのは最適化ではありません)。

于 2012-11-12T22:21:09.157 に答える
3

組み込み型の初期化子リストを使用していますが、パフォーマンス上の利点が得られないため、コンストラクター本体内のチェック後にメンバー変数への割り当てを行わないでください。あなたの場合、半分作成された合法的なオブジェクトではなく、半分作成された違法なオブジェクトがあります。それでは、オブジェクトに無効な状態を与えるのはなぜでしょうか。

コンストラクタから例外をスローしても問題ありません (ほとんどの場合、デストラクタではそうではありません)。渡された値で意味のあることを何もできない場合、つまり、負の値を 0 にバンプすると、例外をスローするように思えます。結局のところ、正当なオブジェクトを作成する立場にありません。

unsigned int を使用できますか? 0 ~ 4,294,967,295。値が > 0 でなければならないことを呼び出し元に対してより明確にします。

于 2012-11-12T22:21:14.243 に答える
0

そのクラスがタイトなループで何度も初期化されない限り、余分な関数によるパフォーマンスの低下は無視できます。これは、不適切に初期化されたクラスが与える可能性のある損害と比較すると、非常に小さな代償です! 特に、「悪い値」はユーザー入力の結果である可能性があるため、発生した問題の報告/トラブルシューティングが困難になる可能性があることを考慮してください

于 2012-11-12T22:23:01.507 に答える
-1

私はこれをしません。クラスを使用している人が、これがそれを使用する賢明な理由であると理解する方法論を使用するだけです。

于 2012-11-12T23:38:38.497 に答える