7

我在 C++ 中工作,我需要知道标量值(例如 a 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++ 中可能吗?

谢谢

4

9 回答 9

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;
}
于 2009-01-23T15:17:06.770 回答
6

正如其他人指出的那样,没有什么比“未定义”状态更重要了。但你可能想看看boost.optional

于 2009-01-23T15:18:07.050 回答
3

如果您的意思是在运行时,则没有这样的事情。如果bar从未初始化,它将具有任何随机位,具体取决于对象的分配方式(某些分配器会将新内存初始化为全零)。

编辑:由程序员在构造函数和/或手动初始化方法中处理对象状态,例如init()

于 2009-01-23T15:13:31.207 回答
2

C++ 没有原始类型的“未定义”状态。最接近浮点/双精度的是 NAN,但这确实有不同的含义。

于 2009-01-23T15:14:24.390 回答
2

为什么不维护一个单独的标志,该标志被初始化为 false,然后在计算 bar 时设置为 true。然后可以通过再次将标志设置为 false 来“取消定义”。

if(!isBarValid)
{
    calculateBar();
    isBarValid = true;
}
return bar;
于 2009-01-23T15:17:54.867 回答
1

这在 C/C++ 中是不可能的,原语将始终分配一个值(主要是垃圾,无论在它之前的内存中的那个位置,除非在声明时显式分配)。我通常有一个占位符值(即指针为 0),它表示未使用,但是也必须显式分配这些值。如果你的 double 可以取任何值,那么我建议你在它旁边放一个布尔值,最初分配为 false,然后在你想进行计算时测试/设置那个值。

于 2009-01-23T15:15:49.783 回答
1

您可以在第一次使用惯用语时尝试Construct并这样编写get_bar()

double & get_bar()
{
    static double *bar = new double(something());
    return *bar;
}

当您打电话时,如果没有人要求get_bar()它,它将为您服务。bar任何后续调用都将返回bar。正如链接页面所说,这在技术上不会泄漏内存,因为操作系统会在程序退出时回收它。

更新:

将返回值更改double &为允许您修改bar.

于 2009-01-23T15:28:28.743 回答
0

初始化为在构造函数中bar调用函数时永远不会出现的某个值。something()

例如:

Foo(): bar(-1)
{
}

然后检查函数-1中的值get_bar

(嗯,Laserallan 还在 1 分钟前发布了该答案:-( ;-))

于 2009-01-23T15:17:56.020 回答
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 ...
};
于 2009-01-23T15:19:38.217 回答