我正在使用C ++,我需要知道标量值(例如double
)是否已“定义”。如果需要,我还需要能够“取消”它:
class Foo {
public:
double get_bar();
private:
double bar;
void calculate_bar() {
bar = something();
}
};
double Foo::get_bar() {
if ( undefined(bar) )
calculate_bar();
return bar;
}
是否可以在C ++中使用?
由于
答案 0 :(得分:12)
正如其他答案所说,C ++没有这个概念。你可以轻松解决它。
要么你可以在构造函数中初始化bar的未定义值,通常是-1.0或类似的东西。
如果您知道calculate_bar永远不会返回负值,您可以将未定义函数实现为检查< 0.0。
更通用的解决方案是让bool说明是否已定义bar在构造函数中初始化为false,并且在第一次设置时将其更改为true。 boost::optional以优雅的模板方式做到这一点。
这就是你所拥有的代码示例。
class Foo {
public:
double get_bar();
Foo() : barDefined(false) {}
private:
double bar;
bool barDefined;
void calculate_bar() {
bar = something();
}
};
double Foo::get_bar() {
if ( barDefined == false ) {
calculate_bar();
barDefined = true;
}
return bar;
}
答案 1 :(得分:6)
正如其他人所指出的,没有什么比“未定义”状态更好。但您可能需要查看boost.optional
答案 2 :(得分:3)
如果你的意思是在运行时,没有这样的事情。如果永远不会初始化bar
,那么它将具有任何随机位,具体取决于对象的分配方式(某些分配器会将新内存初始化为全零)。
编辑:由程序员处理构造函数中的对象状态和/或手动初始化方法,如init()
答案 3 :(得分:2)
为什么不维护一个单独的标志,该标志被初始化为false,然后在计算bar时设置为true。然后可以通过再次将标志设置为false来“取消”。
if(!isBarValid)
{
calculateBar();
isBarValid = true;
}
return bar;
答案 4 :(得分:1)
对于基本类型,C ++没有“未定义”状态。最接近float / double的是NAN,但这确实有不同的含义。
答案 5 :(得分:1)
这在C / C ++中是不可能的,原语总是会分配一个值(主要是垃圾,除非在声明中明确指定,否则它在它之前的内存中的任何位置)。我常见的是占位符值(即指针为0)表示未使用,但是这些也必须明确指定。如果你的double可以取任何值,那么我建议你在它旁边放一个布尔值,最初分配给false,并在你想要计算时测试/设置那个。
答案 6 :(得分:0)
将bar
初始化为某个值,当您在构造函数中调用something()
函数时,该值永远不会发生。
例如:
Foo(): bar(-1)
{
}
然后检查-1
函数中的值get_bar
。
(嗯Laserallan也在1分钟之前发布了答案:-( ;-))
答案 7 :(得分:0)
您必须使用额外的布尔值。
要使用额外的布尔值实现,您可以尝试类似以下模板的逻辑:
template<typename T>
struct Defined
{
bool defined;
T value;
Defined() : defined(false) {}
Defined(const T& value_) : defined(true), value(value_) {}
... and perhaps other operators here ...
... to make this behave even more like a T ...
};
答案 8 :(得分:0)
您可以尝试Construct on first use idiom并以这种方式写get_bar()
:
double & get_bar()
{
static double *bar = new double(something());
return *bar;
}
当您致电get_bar()
时,如果还没有人要求,它会为您bar
。任何后续调用都将返回bar
。正如链接页面所说,这在技术上不会泄漏内存,因为操作系统会在程序退出时回收它。
更新:
将返回值更改为double &
,以允许您修改bar
。