7

クラス T があるとします。

  1. T には仮想関数がありません。
  2. T インスタンスには状態がありません。
  3. T には、それ自体の静的メンバー インスタンスがあります。
  4. T 自体には他の状態はありません。

C++ の静的初期化の大失敗により、プログラムが台無しになる可能性はありますか? 静的インスタンスの 1 つが使用前に初期化されていなくても、T オブジェクトはステートレスであるため問題にならないため、そうは思いません。

次のような列挙型のクラスに対してこれを行うことに興味があります。


// Switch.h

class Switch {
public:
    static Switch const ON;
    static Switch const OFF;
    bool operator== (Switch const &s) const;
    bool operator!= (Switch const &s) const;
private:
    Switch () {}
    Switch (Switch const &); // no implementation
    Switch & operator= (Switch const &); // no implementation
};

// Switch.cpp

Switch const Switch::ON;
Switch const Switch::OFF;

bool Switch::operator== (Switch const &s) const {
    return this == &s;
}

bool Switch::operator!= (Switch const &s) const {
    return this != &s;
}
4

3 に答える 3

2

あなたの質問の最初の部分に答えるために、T副作用のあるコンストラクターがある場合、実際には静的初期化の大失敗によって火傷を負う可能性があります。

于 2011-05-16T22:34:10.630 に答える
2

たとえば、名前空間またはクラスのいずれかにラップされた列挙型から得られる利点に興味があります。

namespace Switch {
   enum Switch {
      ON,
      OFF
   };
}

ほとんどの場合、使用が簡単になり (実装では、オブジェクトはコピーできないため、ユーザーは参照またはポインターを使用する必要があります)、必要なコードが少なくなります (コンストラクターを無効にして演算子を作成する必要はありません)。 ..

実際のところ、今後の標準では、名前空間を使用しなくてもほとんど無料で取得できます。

enum Switch {
   ON,
   OFF
};
// bad, it allows this (as in the current standard):
Switch s = ON;
// good, it does also allow explicit qualification:
Switch s = Switch::ON;
于 2011-05-16T22:19:14.127 に答える
0

「状態」を比較するためにポインター値を使用するつもりですか? @Drew に同意します。興味深いアイデアです。ただし、これがヘッダーのみの実装であると仮定すると、標準で機能することが保証されているかどうかはわかりません。

Switch::ON複数のコンパイル オブジェクトにとの同じ定義が含まれているとどうなるかを考えてみましょうSwitch::OFF。これらは関数ではなく変数であるため、リンカはそれらの間で任意に決定する必要があります。

テストを実行したとき、一般的なコンパイラ (gcc 3、gcc 4、Microsoft C++ 2005、2008、2010、およびhttp://www.comeaucomputing.com/などの Edison Design Groups のコンパイラの 1 つ) は何を言いましたか?

このテストは、次のもので構成されます。

// Switch.h
class Switch {
public:
    static Switch const ON;
    static Switch const OFF;
    bool operator== (Switch const &s) const;
    bool operator!= (Switch const &s) const;
private:
    Switch () {}
    Switch (Switch const &); // no implementation
    Switch & operator= (Switch const &); // no implementation
};

Switch const Switch::ON;
Switch const Switch::OFF;

bool Switch::operator== (Switch const &s) const {
    return this == &s;
}

bool Switch::operator!= (Switch const &s) const {
    return this != &s;
}

// main.cpp
#include "Switch.h"

extern int another_test();

int main(int argc, char*argv[])
{
  another_test();
  const Switch& current_state = Switch::ON;
  const Switch& another_state = Switch::OFF;
  if (current_state == another_state) {
    return 1;
  } else if (current_state != another_state) {
    return 2;
  }
  return another_test();
}

// another_test.cpp
#include "Switch.h"

int another_test()
{
  const Switch& current_state = Switch::ON;
  const Switch& another_state = Switch::OFF;
  if (current_state == another_state) {
    return 4;
  } else if (current_state != another_state) {
    return 5;
  }
  return 6;
}
于 2011-05-16T22:12:58.687 に答える