質問
C ++でクラスコンストラクターを再設計していますが、不特定のboolをキャッチする必要があります。私は他のすべてのパラメーターにデフォルト値を使用しましたが、私の理解ではboolはtrueまたはfalseにのみ初期化できます。これらのケースは両方ともクラスで意味があるため、デフォルト値からの変更のチェックをどのように処理する必要がありますか?
解決
現実には、これを行うことはできません。 boolにはtrueまたはfalseの値があり、初期化していない場合はランダムにtrueまたはfalseになり、プログラムの実行またはそのクラスの割り当てごとに異なる可能性があります。
より多くのオプションを持つ型が必要な場合は、enumを定義します。
typedef enum MyBool {
TRUE,
FALSE,
FILENOTFOUND
} MyBool;
他のヒント
トライステートboolは、ダークサイドへのパスです。トライステートブールは怒りにつながります。怒りは憎しみにつながります。憎しみは苦しみにつながります。
トライステートブールを使用しないこと。
代わりに、最初のブール値が<!> quot; initialized <!> quot;であるかどうかに追加のブール値を1つ使用します。 (または、<!> quot; known <!> quot;)またはそうではありません。
class Prisoner : public Person
{
...
bool is_veredict_known;
bool is_guilty;
}
判決がまだ知られていない場合、囚人が本当に有罪かどうかはわかりませんが、コードは異なる状況を区別できます。もちろん、憲法はis_guiltyのデフォルト値がfalseであることを保証していますが、それでも...:)
ところで、クラス不変式には以下が含まれている必要があります:
assert(is_veredict_known || !is_guilty);
それが必要な場合は、初期化されていない可能性のある値の概念を表す値を作成します。
template <typename T>
struct Maybe {
Maybe() : m_hasValue(false) {}
bool HasValue() const { return m_hasValue; }
T& Value() { ThrowIfFalse(m_hasValue); return m_value; }
const T& Value() const { ThrowIfFalse(m_hasValue); return m_value; }
void SetValue( _In_ const T& value) { m_value = value; m_hasValue = true; }
private:
bool m_hasValue;
T m_value;
};
これで、必要な3つの状態すべてを表すことができます。
class SomeType {
...
Maybe<bool> m_myBool;
}
C ++では、bool
は1ビットの情報であり、0または1のいずれかです。3つの可能な状態を表すには、もう1ビットの情報が必要です。 2つの一般的な手法があります。
- 別の<=>値を使用して、値が<!> quot; default <!> quotであるかどうかを示します。かどうか、または
- 3つの値を持つ列挙型を使用して(デフォルト、true、false)を示します。
おそらくオプション1を選択します。
struct Bool { //guaranteed initialized bool
bool v;
Bool() : v(false) {}
operator bool() const { return v; }
bool& operator=(const bool val){ return v = val; }
};
great boost :: optionalを使用します。ブールだけでなく、使用した他のすべての場所にも いくつかの汚れた初期化されていない値。これは次のように使用されます。
void function(optional<int> value) {
if (value)
std::cout << "value is defined: " << value.get() << "\n";
else
std::cout << "value is not defined\n";
}
そして、これはオプションを返す関数の例です:
struct MapClass {
map<string,int> m_map;
optional<int> getValue(string key) {
optional<int> result = none;
if (m_map.find(key) != m_map.end())
result = m_map[key];
return result;
}
}
bool値が実際に初期化されたかどうかを示す個別のプライベートメンバーを持つことができます。
よくわかりませんが、試してみます...
一部の値を指定しない集約初期化子がある場合、デフォルト値が適用されます。その場合、boolのデフォルトはfalseになります。クラスでは、<!> quot; default <!> quot;値は初期化されていません。つまり、値は任意で、実行ごとに変わる可能性があります。
boolが変更されたかどうかに関心がある場合、最善のオプションは、2番目のboolをデフォルトでfalseにして追跡するか、3つの可能な状態を表す列挙型を使用することです。本当に3つの状態が必要な場合、boolは必要ありません。
本当にできません。たとえば、2番目のコンストラクタを提供できますか:
class MyClass {
public:
MyClass(bool bFlag); // <-- not default
MyClass(void); // <-- default
};
ブール値の代わりに、列挙を使用します。たとえば、魔法のレベルを制御するには:
enum {
MY_ENUM_NO_MAGIC,
MY_ENUM_SOME_MAGIC,
MY_ENUM_MORE_MAGIC
} MagicLevel;
次に、コンストラクターにパラメーターMagicLevel magic = MY_ENUM_NO_MAGIC
を受け入れさせます。
class aclass
{
<stuff> lots of other things
bool mybool
bool ismyboolinit
void setmybool(bool b)
{
mybool = b;
ismyboolinit = true;
}
}
関数とクラスを使用する場合は、それらをオーバーロードするだけです。
ie:
class thing
{
public:
void f1(bool); // bool input
void f1(int = 3); // default with out bool being known
private:
// stuff
};
void thing::f1 (bool hasAFace)
{
if(hasAFace)
f1(0);
if(!hasAFace)
f1(1);
}
void thing::f1 (int tri)
{
bool actionTime;
if(tri == 1)
actionTime = true;
else if(tri == 0)
actionTime = false;
else
//input defualt action here.
}
//そしてそこに行きます。また、オーバーロードされた関数を使用するだけのクラスは必要ありません。