سؤال
أقوم بإعادة تصميم مُنشئ الفصل في C++ وأحتاجه لالتقاط منطقي غير محدد.لقد استخدمت القيم الافتراضية لجميع المعلمات الأخرى، ولكن من وجهة نظري لا يمكن تهيئة المنطق إلا إلى صواب أو خطأ.نظرًا لأن كلتا الحالتين لهما معنى في الفصل، فكيف يجب أن أتعامل مع التحقق من التغيير من القيمة الافتراضية؟
المحلول
والحقيقة هي أنك لا تستطيع أن تفعل هذا. ومنطقي له قيمة، إما صحيحة أو خاطئة، وإذا لم تكن قد تهيئته ثم كان صحيحا أو خاطئا بشكل عشوائي، وربما مختلفة في كل شوط من البرنامج أو تخصيص تلك الفئة.
إذا كنت بحاجة إلى نوع مع مزيد من الخيارات، تعريف التعداد.
typedef enum MyBool {
TRUE,
FALSE,
FILENOTFOUND
} MyBool;
نصائح أخرى
Tristate bool هو الطريق إلى الجانب المظلم.يؤدي بول Tristate إلى الغضب.الغضب يؤدي إلى الكراهية.الكراهية تؤدي إلى المعاناة.
يفضل عدم استخدام bool ثلاثي الحالة.
بدلاً من ذلك، استخدم قيمة منطقية إضافية لمعرفة ما إذا كان القيمة المنطقية الأولى "تمت تهيئتها" (أو الأفضل "معروفة") أم لا.
class Prisoner : public Person
{
...
bool is_veredict_known;
bool is_guilty;
}
إذا لم يكن الحكم معروفًا بعد، فلا يمكنك معرفة ما إذا كان السجين مذنبًا حقًا، ولكن الكود الخاص بك يمكنه التمييز بين المواقف المختلفة.بالطبع يؤكد الدستور أن القيمة الافتراضية لـ is_guilty يجب أن تكون خاطئة، ولكن لا يزال...:)
بالمناسبة، يجب أن يتضمن الفصل الثابت ما يلي:
assert(is_veredict_known || !is_guilty);
وهذا يبدو وكأنه كنت تريد تعزيز :: tribool أ > تعزيز :: اختياري <منطقي > .
وإذا كان هذا هو ما تحتاج إليه، إنشاء قيمة التي تمثل مفهوم القيمة التي ربما لم تتم تهيئة.
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
هي عبارة عن بت واحد فقط من المعلومات، إما 0 أو 1.وبما أنك تريد تمثيل ثلاث حالات محتملة، فأنت بحاجة إلى معلومة إضافية.هناك نوعان من التقنيات العامة:
- استخدم آخر
bool
value للإشارة إلى ما إذا كانت القيمة "افتراضية" أم لا، أو - استخدم نوع التعداد بثلاث قيم للإشارة إلى (افتراضي، صحيح، خطأ).
ربما سأختار الخيار 1.
struct Bool { //guaranteed initialized bool
bool v;
Bool() : v(false) {}
operator bool() const { return v; }
bool& operator=(const bool val){ return v = val; }
};
استخدم لدفعة كبيرة :: اختياري. وليس فقط لbools ولكن لجميع الأماكن الأخرى التي تستخدم بعض القذرة القيم يست تهيئة في ويستخدم مثل هذا:.
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;
}
}
هل يمكن أن يكون عضو خاص منفصل الذي يشير إلى ما إذا كان قد تم بالفعل تهيئة قيمة منطقي أم لا.
وأنا لا أفهم تماما، ولكن سأحاول ...
يتم تطبيقوالقيم الافتراضية عندما يكون لديك مهيئ الكلي الذي يترك بعض القيم غير محددة. في هذه الحالة، فإن الافتراضي منطقي لتكون كاذبة. في فئة، فإن قيمة "الافتراضي" يكون غير مهيأ، وهذا يعني أنه يمكن أن يكون أي قيمة، ويمكن أن تتغير من التشغيل لتشغيل.
إذا كنت ترغب في وجود أو عدم منطقي قد تغيرت، والخيار الأفضل لك هو أن تتبع ذلك مع منطقي الثاني المتعثرة إلى false، أو استخدام التعداد تمثل 3 ولايات ممكنة. إذا كنت تريد حقا 3 ولايات، هل حقا لا تريد منطقي.
وكنت حقا لا يمكن. هل يمكن توفير منشئ الثاني، على سبيل المثال:
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;
}
}
وحسنا إذا كان لديك باستخدام وظائف والطبقات، مجرد الزائد منها.
وأي:
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.
}
و// وهناك تذهب. أيضا لا تحتاج أن يكون لها درجة التي يمكن أن مجرد استخدام وظائف مثقلة.