質問

C ++で作業していますが、スカラー値(たとえばdouble)が<!> quot; defined <!> quot;であるかどうかを知る必要があります。か否か。また、<!> quot; undef <!> quot;必要に応じて:

class Foo {
public:
    double get_bar();

private:
    double bar;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( undefined(bar) )
        calculate_bar();
    return bar;
}

C ++では可能ですか?

ありがとう

役に立ちましたか?

解決

他の回答にあるように、C ++にはこの概念がありません。ただし、簡単に回避できます。

コンストラクタでbarを初期化する未定義の値を持つことができます。通常は-1.0などです。

calculate_barが負の値を返さないことがわかっている場合、<!> ltのチェックとして未定義関数を実装できます。 0.0。

より一般的な解決策は、コンストラクタでfalseに初期化されたバーがまだ定義されているかどうかを示すブール値を持ち、最初に設定したときにtrueに変更することです。 boost :: optional はこれを行いますエレガントなテンプレート化された方法。

これは、あなたが持っているコード例です。

class Foo {
public:
    double get_bar();
    Foo() : barDefined(false) {}
private:
    double bar;
    bool barDefined;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( barDefined == false ) {
        calculate_bar();
        barDefined = true;
    }
    return bar;
}

他のヒント

他の人が指摘したように、<!> quot; undefined <!> quot;のようなものはありません。状態。ただし、 boost.optional

実行時に意味する場合、そのようなことはありません。 barが初期化されない場合、オブジェクトの割り当て方法に応じて、ランダムビットが存在します(一部のアロケーターは新しいメモリをすべてゼロに初期化します)。

編集:コンストラクターおよび/またはinit()

などの手動初期化メソッドでオブジェクトの状態を処理するのはプログラマーの責任です

falseに初期化され、barの計算時にtrueに設定される個別のフラグを保持しない理由。フラグを再度falseに設定することで、「未定義」になります。

if(!isBarValid)
{
    calculateBar();
    isBarValid = true;
}
return bar;

C ++には<!> quot; undefined <!> quot;はありません。プリミティブ型の状態。 float / doubleに最も近いものはNANですが、実際には別の意味があります。

これはC / C ++では不可能であり、プリミティブは常に値が割り当てられます(宣言で明示的に割り当てられていない限り、ほとんどがガベージ、その前にメモリ内のその場所にあったものはすべて)。私は、未使用を示すプレースホルダー値(つまり、ポインターの場合は0)を持つのが一般的ですが、これらも明示的に割り当てる必要があります。 doubleが任意の値を取ることができる場合、最初にfalseに割り当てられたブール値をその横に配置し、計算を実行するときにその値をテスト/設定することをお勧めします。

追加のブール値を使用して実行する必要があります。

追加のブール値を使用して実装するには、次のテンプレートのようなロジックを試すことができます:

template<typename T>
struct Defined
{
 bool defined;
 T value;
 Defined() : defined(false) {}
 Defined(const T& value_) : defined(true), value(value_) {}
 ... and perhaps other operators here ...
 ... to make this behave even more like a T ...
};

初回使用イディオムで構築このようにget_bar()と書きます:

double & get_bar()
{
    static double *bar = new double(something());
    return *bar;
}

barを呼び出すと、まだ誰も要求していない場合にdouble &が作成されます。後続の呼び出しは、単に<=>を返します。リンクされたページにあるように、プログラムが終了するとOSがメモリを再利用するため、技術的にメモリリークはありません。

更新:

<=>を変更できるように戻り値を<=>に変更しました。

barをコンストラクターでsomething()関数を呼び出したときに決して発生しない値に初期化します。

例:

Foo(): bar(-1)
{
}

次に、-1関数の値get_barを確認します。

(hmmm Laserallanはその回答を1分前に投稿しました:-( ;-))

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top