2017-04-20 9 views
3

ボタンを表すクラスを記述しています。このボタンには、テキスト、ショートカット、テクスチャまたはフラットカラーの塗りつぶしなどのさまざまな属性がある場合とない場合があります。たとえば、このボタンにテクスチャが設定されていない場合、テクスチャ描画処理はスキップされます。std :: optionalと "unused/default"の値の使用

私の最初の解決策は、指定された属性が使用されていない(色のアルファ値が0だった場合、カラー塗りの描画をスキップするなど)デフォルト値を使用することでした。

私が持っているその他のオプションは、新しく追加されたstd :: optionalを使うことです。これははるかに明確で使いやすいでしょう。ここで

は2つの言及した例です:

class Button { 
    void draw() { 
     if (fill) 
      drawRectangle(*fill); 
     if (sprite) 
      drawSprite(*sprite); 
     if (font) 
      drawText(name, *font); 
    } 

    std::optional<std::string> font; 
    std::optional<std::string> sprite; 
    std::optional<Color> fill; 
} 

class Button { 
    void draw() { 
     if (fill.alpha != 0) 
      drawRectangle(fill); 
     if (sprite != "") 
      drawSprite(sprite); 
     if (font != "") 
      drawText(name, font); 
    } 

    std::string font; 
    std::string sprite; 
    Color fill; 
} 

のstd ::オプションを使用することの利点とdisadvatagesが、この場合に何をすることができますか?私が主に興味を持っているのは、メモリ使用量とオーバーヘッドの違いです。

また、ifを使用してvalueに値が含まれているかどうかをチェックする代わりに、value()をコールして例外をキャッチする必要がありますか?

+3

'.value()'を使用し、値を持っているかどうかをチェックするのではなく、例外をキャッチすることに関して、あなたの質問に関して:それは悪い考えです。名前が示すように、例外は例外的なケースであり、スタックアンローリングによるオーバーヘッドは無視できません。例えば、多くのボタンが使用されていると仮定する。色はありません。オプションの空白は例外的なケースではありません。 – Corristo

+0

空の文字列が文字列とまったく違っていない限り、 'std :: optional 'は非常に便利です。 –

+0

'std :: optional'は、クラスのメンバーではなく、関数の戻り値のためのものです。これはかなり無駄なことです。また、 'sprite.exy()'は 'sprite ==" "'上で使用されるべきです。 – Pubby

答えて

4

オーバーヘッドは、ほとんどの場合、スペースの形です。 optionalは、格納されているものと、ブール値のアライメントを行うための余分なパディングを常に使用します。たとえば、std::stringは、8バイトアライメントの24バイトとして実装されることがよくあります。 optional<string>は25バイトになりますが、位置合わせのために32バイトになります。プリミティブ型(intまたはenum)の場合、通常は4から8バイトなどの必要な記憶領域を2倍にします。

パフォーマンスが向上する限り、この場合、キャッシュ・エフェクト以外では(オプティマイザがスマートな場合)違いはありません。 std::stringと空の文字列リテラルを比較すると、おそらくstd::string::emptyへの呼び出しに最適化されます(おそらくそれを書くべきでしょう)。これは、整数がゼロかどうかを確認することです。これはColorの比較ブール値がゼロかどうかのチェックと同じです。

それは私が好きだと言ったoptional;私はそれがコードの意図をより明確に伝えていると思います。しかし、あなたが非常に明白なセンチネル値を持っているなら、多分それはあまり価値がありません。

場合によっては、ケーキを食べてコンパクトでも食べることができます(https://github.com/akrzemi1/compact_optional)。それは通常のオプションと同じ外部インタフェースを持ちますが、あなたはそれにセンチネル値を与え、そのセンチネルを使用して欠落状態を格納します。すべてのクラスでうまく動作しないかもしれません。

+3

+1。重要なテイクアウェイは、「**より明確にインテントを伝える**」と「**あなたが非常に明白なセンチネル値を持っていれば、それほど価値がないかもしれません**」という意図を明確に伝えることは、誤用しにくい " – sp2danny

1

std :: optionalには余分なブール値のオーバーヘッドが発生することがありますが、ここには説明的な目的もあります。コードに入れようとしているコンセプトを完全に表しています。続行中です。これはUIなので、ブール値のオーバーヘッドは比較的小さいので、私はそれを求めています。

std :: optionalは関数が返すためだけのものであるという陳述に賛成です。それはばかげて制限されるでしょう。

関連する問題