문제
나는 C ++에서 클래스 생성자를 재 설계하고 있으며 지정되지 않은 bool을 잡아야합니다. 다른 모든 매개 변수에 대한 기본값을 사용했지만 내 이해에서 Bool은 True 또는 False로만 초기화 될 수 있습니다. 이 두 경우 모두 수업에서 의미가 있으므로 기본값에서 변경 사항을 확인하는 방법을 어떻게 처리해야합니까?
해결책
현실은 당신이 이것을 할 수 없다는 것입니다. bool은 true 또는 false의 값을 가지며, 초기화되지 않은 경우 프로그램의 실행 또는 해당 클래스의 할당마다 무작위로 true 또는 false 일 수 있습니다.
더 많은 옵션이있는 유형이 필요한 경우 열거를 정의하십시오.
typedef enum MyBool {
TRUE,
FALSE,
FILENOTFOUND
} MyBool;
다른 팁
Tristate Bool은 어두운면으로가는 길입니다. Tristate Bool은 분노로 이어집니다. 분노는 미워로 이어집니다. 증오는 고통으로 이어집니다.
Tristate Bool을 사용하지 않는 것이 좋습니다.
대신, 첫 번째 부울이 "초기화"(또는 더 나은, "알려진")인지 여부에 대해 추가 부울 하나를 사용하십시오.
class Prisoner : public Person
{
...
bool is_veredict_known;
bool is_guilty;
}
Veredict가 아직 알려지지 않은 경우 죄수가 실제로 유죄인지 알 수 없지만 코드는 다른 상황을 구별 할 수 있습니다. 물론 헌법은 is_guilty의 기본값이 거짓이어야하지만 여전히 ... :)
그건 그렇고, 클래스 불변은 다음을 포함해야합니다.
assert(is_veredict_known || !is_guilty);
당신이 원하는 것 같습니다 부스트 :: tribool 아니면 어쩌면 부스트 :: 선택 사항u003Cbool>.
그것이 필요한 것이라면, 초기화되지 않은 값의 개념을 나타내는 값을 만듭니다.
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 ++에서 a bool
0 또는 A 1의 정보는 하나뿐입니다. 3 개의 가능한 상태를 나타내려면 하나의 정보가 하나 더 필요합니다. 두 가지 일반적인 기술이 있습니다.
- 다른 것을 사용하십시오
bool
값이 "기본"인지 아닌지를 나타내는 값 - 세 가지 값의 열거 유형을 사용하여 (기본값, 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; }
};
큰 부스트 :: 선택 사항을 사용하십시오. 그리고 부울뿐만 아니라 다른 모든 장소에서는 더러운 이니셜 값을 사용했습니다. 이와 같이 사용됩니다.
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입니다. 클래스에서 "기본"값은 초기화되지 않으므로 값이 될 수 있으며 실행에서 실행으로 변경 될 수 있습니다.
부울이 변경되었는지 여부에 관심이 있다면, 가장 좋은 선택은 두 번째 bool이 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.
}
// 당신은 간다. 또한 과부하 된 기능 만 사용할 수있는 클래스가 필요하지 않습니다.