测试 C++ 对象的有效性,就好像它是一个指针一样

Test a C++ object validity as though it was a pointer

假设我有一个可能没有正确初始化的对象,但它不仅仅是指向对象的空指针;它是一个具有空成员或未初始化成员的对象。但我想以一种可读的方式检查它,就好像它是一个指针一样:

if (Object) use(Object);

例如,Object 可能有一个 int 字段,如果该字段为 0,则被视为未初始化。然后,我可以重载 !像这样的运算符:

bool operator!() const {return intField == 0;}

我可以这样使用:

if (! Object)  initialize (Object);

问题是,如果我想测试相反的条件(非空性),我不能这样做:

if (Object)...

我只发现尴尬的可能性:

if (! (! Object))...  // awful
if (Object.notNull()) // not so bad

最接近我愿望的那个令人困惑:

bool operator()() {return intField != 0;}
if (Object())...   // it looks a lot like an argument-less constructor

据我所知,没有返回布尔值的空运算符(类似于 bool operator() {...})或任何其他可以实现此目的的技巧或习语。

除了 notNull() 方法之外,还有其他可读解决方案的想法吗?谢谢。

您可以提供类型转换运算符,以允许转换为 bool:

explicit operator bool() const {return intField != 0;}

这允许它在布尔上下文中使用,例如 if 条件。 explicit 是可选的,但它是一个好主意,可以防止对数字类型的潜在混淆转换。

另一种方法是使用 Boost.Optional 或类似方法,使任何类型都可以为 null。

我认为您要小心使用运算符重载来指示有效性或初始化状态——尤其是如果您将持有指向此类对象的指针或引用时。

对于这种情况,我建议使用以下显式表示法:

if (Object.isValid()) use(Object);

这样,对于下一个阅读您代码的人来说,您在此处所做的事情就一目了然。运算符重载对使用它的人来说应该总是显而易见的,对对象的 true/false 检查意味着它 存在 或不存在,不一定 有效与否。