定义双重感叹?

Cem*_*mre 13 c++ boolean logical-operators

我理解双重感叹号的作用(或者我认为我理解),但我不确定它是如何在随机对象上定义的.例如,在下面的代码段中:

Assignment *a;
if (!getAssignment(query, a))
   return false;
hasSolution = !!a;

if (!a)
   return true;
Run Code Online (Sandbox Code Playgroud)

我怎么知道双重感叹号会产生什么价值?换句话说,它总是转换为真?假?或者你能为它定义一个行为,比如执行一个方法来确定结果(对象如何知道在这种情况下如何行动)?由于所有这些感叹事件的发生,我对这段代码感到有点困惑.任何解释都表示赞赏.

希望我很清楚,谢谢.

Jef*_*mas 17

a是一个指针.在C++中,nullptr被定义为无效指针.!pointernullptr指针转换true为非nullptr指针false.!booleantruefalsefalsetrue.它总是有效的.

!(!a) 是一种有用的思考方式.


Oli*_*rth 9

不要把它想象成"双重感叹号",把它想象成两个独立的运算符,一个运行在另一个运算符的结果上.

对于所有原始类型,它将"起作用". !a相当于a == 0,相当于,!!a相当于!(a == 0),相当于a != 0.

对于用户定义的类型,除非重载,否则不会编译operator !.但显然,在这种情况下,行为几乎可以是任何事情.


CB *_*ley 5

!!不是 C++ 中的单个标记,只是解析为!两次应用运算符。

由于a是指针而不是类类型的对象,!因此不能重载。它被定义为true如果a是空指针false则返回,否则返回。

的第二个应用程序!简单地否定了第一个 的结果!

表达式!!a等价于a != 0


Kon*_*lph 5

代码极其复杂。实际上,您想要测试该getAssigment方法是否成功以及分配的指针是否为非空。

\n\n

该代码测试了这一点,尽管是以一种复杂的方式,但利用了弱类型,而不是试图拥抱显式性和 C++\xe2\x80\x99 强类型。因此,它\xe2\x80\x99 不是惯用的 C++,而且比必要的更难理解。

\n\n

特别是,不要!!a在 C++ 中使用\xe2\x80\x99t。这是弱类型语言(例如 JavaScript)中的一种既定习惯用法,用于将值强制转换为布尔类型。但在C++中,这并不常用

\n\n

hasSolution由于未定义或使用,因此不清楚代码的作用。但是,我怀疑该代码应该等同于以下内容:

\n\n
Assignment *a;\nreturn getAssignment(query, a) and a == nullptr;\n
Run Code Online (Sandbox Code Playgroud)\n\n

(在 C++11 之前,您需要编写0而不是nullptr。)

\n\n

然而,这段代码仍然暴露了一个糟糕的设计:为什么是a通过引用传递?为什么\xe2\x80\x99不是返回值?更糟糕的是,a从来没有使用过,所以没有必要。如果a确实没有必要,则应完全排除。如果需要的话,它应该是返回值。也就是说, 的原型getAssignment应该如下:

\n\n
Assignment* getAssignment(the_type_of_query query);\n
Run Code Online (Sandbox Code Playgroud)\n\n

它应该简单地使用如下:

\n\n
Assignment* a = getAssignment(query);\n
Run Code Online (Sandbox Code Playgroud)\n\n

此外,我怀疑这段代码实际上将内存所有权分配给了原始指针a。现代 C++ 中强烈建议不要这样做。要么不使用指针,要么使用智能指针。

\n