检查C ++中的值定义

时间:2009-01-23 15:11:12

标签: c++ undef

我正在使用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 ++中使用?

由于

9 个答案:

答案 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