如何检查布尔值是否在 C++ 中未初始化?
how to check whether a boolean is uninitialized in c++?
我想为对象的某些(难以计算的)布尔属性创建缓存。我想到的结构如下:
class Obj;
struct ObjProperties
{
bool property1;
bool property2;
// etc.
};
std::unordered_map<const Obj*, ObjectProperties> cache;
现在我想拥有类似
的功能
bool hasProperty1()
{
if /*(cache[property1] is uninitialized)*/
cache[property1] = calculateProperty1();
return cache[propery1];
}
然而我如何检查布尔值是否未初始化? Property1 可以是 true 或 false,所以我无法将它初始化为一个值...
我看到两种处理方法:
1) 使我的结构 bool*
的成员成为指针。然后我可以检查 nullptr
,但这使我的函数变得有点麻烦,因为我必须 new
/delete
我所有的布尔对象
2) 使我的结构成员成为 int
。然后我可以将它们初始化为 -1 并分配 0(假)或 1(真)。但这使我的代码不那么明显。毕竟,这些属性是布尔值,我的缓存结构实际上也包含一些(真实的)整数和双精度数。
处理此问题的最佳方法是什么?还是我忽略了一些非常简单的测试来检查布尔值是否未初始化?
您无法立即知道 POD 类型是否已初始化。编译器分配给变量的内存将有一个值;是否有效,取决于您。
判断变量是否初始化的一种方法是使用 bool
变量。
另一种首选方法是始终在 struct
、class
或函数的构造函数中初始化它们。
编辑 1:
如果将变量定义为 static
,它将在 main
之前初始化(与全局变量一样)或在第一次进入函数时初始化。
对于您的情况,我强烈建议您创建一个 constructor
方法来初始化 struct
中的变量。
您不能强制对内置类型进行初始化,但您可以改用包装器(如果偏执狂,请查询):
/// Initialize a type with zero.
template <typename T>
struct Zero
{
T value;
operator const T& () const { return value; }
operator T& () { return value; }
Zero()
: value(0)
{}
Zero(const T& initializer)
: value(initializer)
{}
};
struct Some
{
Zero<bool> property;
};
以上仅确保零(假)初始化。您可以更改模板以支持 true(也),或选择反映 false 状态的名称(大写与 no_uppercase)
拥有 C++11,我更喜欢:
struct Some
{
bool property = false;
};
如果成员未初始化,则行为不明确。
如果您只有几个属性:
class ObjProperties
{
bool property1;
bool property1_valid;
bool property2;
bool property2_valid;
ObjProperties() : property1_valid(false), property2_valid(false)
{}
}
您可以实现一个特殊的 属性 类型:
struct BoolProperty
{
bool value;
bool valid;
BoolProperty() : value(false), valid(false) {}
BoolProperty(bool value) : value(value), valid(true) {}
BoolProperty &operator=(const bool &arg)
{
value = arg;
valid = true;
}
bool isValid() const { return valid; }
...
}
class ObjProperties
{
BoolProperty property1;
BoolProperty property2;
}
或者你可以使用一些位域:
class ObjProperties
{
bool property1;
bool property2;
int property1_valid:1;
int property2_valid:1;
}
我想为对象的某些(难以计算的)布尔属性创建缓存。我想到的结构如下:
class Obj;
struct ObjProperties
{
bool property1;
bool property2;
// etc.
};
std::unordered_map<const Obj*, ObjectProperties> cache;
现在我想拥有类似
的功能bool hasProperty1()
{
if /*(cache[property1] is uninitialized)*/
cache[property1] = calculateProperty1();
return cache[propery1];
}
然而我如何检查布尔值是否未初始化? Property1 可以是 true 或 false,所以我无法将它初始化为一个值...
我看到两种处理方法:
1) 使我的结构 bool*
的成员成为指针。然后我可以检查 nullptr
,但这使我的函数变得有点麻烦,因为我必须 new
/delete
我所有的布尔对象
2) 使我的结构成员成为 int
。然后我可以将它们初始化为 -1 并分配 0(假)或 1(真)。但这使我的代码不那么明显。毕竟,这些属性是布尔值,我的缓存结构实际上也包含一些(真实的)整数和双精度数。
处理此问题的最佳方法是什么?还是我忽略了一些非常简单的测试来检查布尔值是否未初始化?
您无法立即知道 POD 类型是否已初始化。编译器分配给变量的内存将有一个值;是否有效,取决于您。
判断变量是否初始化的一种方法是使用 bool
变量。
另一种首选方法是始终在 struct
、class
或函数的构造函数中初始化它们。
编辑 1:
如果将变量定义为 static
,它将在 main
之前初始化(与全局变量一样)或在第一次进入函数时初始化。
对于您的情况,我强烈建议您创建一个 constructor
方法来初始化 struct
中的变量。
您不能强制对内置类型进行初始化,但您可以改用包装器(如果偏执狂,请查询):
/// Initialize a type with zero.
template <typename T>
struct Zero
{
T value;
operator const T& () const { return value; }
operator T& () { return value; }
Zero()
: value(0)
{}
Zero(const T& initializer)
: value(initializer)
{}
};
struct Some
{
Zero<bool> property;
};
以上仅确保零(假)初始化。您可以更改模板以支持 true(也),或选择反映 false 状态的名称(大写与 no_uppercase)
拥有 C++11,我更喜欢:
struct Some
{
bool property = false;
};
如果成员未初始化,则行为不明确。
如果您只有几个属性:
class ObjProperties
{
bool property1;
bool property1_valid;
bool property2;
bool property2_valid;
ObjProperties() : property1_valid(false), property2_valid(false)
{}
}
您可以实现一个特殊的 属性 类型:
struct BoolProperty
{
bool value;
bool valid;
BoolProperty() : value(false), valid(false) {}
BoolProperty(bool value) : value(value), valid(true) {}
BoolProperty &operator=(const bool &arg)
{
value = arg;
valid = true;
}
bool isValid() const { return valid; }
...
}
class ObjProperties
{
BoolProperty property1;
BoolProperty property2;
}
或者你可以使用一些位域:
class ObjProperties
{
bool property1;
bool property2;
int property1_valid:1;
int property2_valid:1;
}