非void函数可能缺少返回
Non-void function potential lack of return
我写了这段代码来检查节点是树中的左子节点还是右子节点。然而,从清洁的角度来看,我认为它没有得到适当的实施。
我的问题是,如果父指针为null,则返回类似false的默认值是危险的,因为false意味着它是一个正确的子指针。但是,如果我想在没有警告的情况下编译此函数,则需要返回。作为一种解决方案,空投绝对是丑陋的。
我见过人们使用assert(parent)
而不是if
,但我认为这也不好,因为断言调试功能。
简而言之,有什么更好的想法来实现这一功能?
bool isLeftChild() const {
if(parent){
if(this == (parent->left).get()){
return true;
}
else if(this == (parent->right).get()){
return false;
}
}
else throw;
}
清洁度最终取决于意见。您遇到的问题是这个函数的约定是什么。也就是说,如果在父节点为NULL的节点上调用该代码,您希望它定义该代码的行为吗?
如果答案是肯定的,那么投掷是完全有效的。很像vector::at
在索引越界时抛出。
bool isLeftChild() const
{
if(!parent) throw ...;
if(this == (parent->left).get()){
return true;
}
else if(this == (parent->right).get()){
return false;
}
}
如果答案是否定的,那么你就不应该扔。这就是vector::operator[]
处理越界索引的方式。在C++20中,您可以将其表示为一个契约:
bool isLeftChild() const
[[expects: parent != nullptr]]
{
if(this == (parent->left).get()){
return true;
}
else if(this == (parent->right).get()){
return false;
}
}
但这在概念上是一种断言;如果在父节点为NULL的节点上调用此函数,则会导致未定义的行为。
哪一个"更干净"取决于你自己以及你希望你的界面如何表现。"宽合约"(你抛出失败而不是调用UB(通常被视为"更安全"的替代方案。这主要是因为你会从出错的地方抛出异常,而不是从其他地方抛出。但在这种特殊情况下,如果parent
为NULL,当您尝试取消引用它时,您会立即发现
但即便如此,在现代C++中,宽契约通常被认为是糟糕的形式。事实上,对于C++20中的合同,委员会正在考虑慢慢删除标准库中抛出logic_error
的位置,将它们变成违反合同的地方(即:UB(。
我想这取决于你想要什么。我认为,如果节点不是任何人的孩子,那么一个名为isLeftChild()
的函数应该返回false
,因为如果它不是任何人,那么它肯定不是左孩子…
关于assert()
的使用,您应该问自己一个问题:在函数被错误调用的情况下,是否有必要保证定义良好的行为?assert()
的目的是捕捉在正确的程序中不应该出现的情况。一旦构建了发布版本,这些检查就不必再进行了,因为它们检查的情况可能(应该(永远不会发生。另外,请注意,除非正在处理活动异常,否则不带参数的throw
表达式将简单地调用std::terminate()
。我怀疑isLeftChild()
是否打算仅从catch
块内部独占调用!?因此,为了让这个throw
做你最可能想做的事情,你需要抛出一些的东西,例如std::logic_error
。
- QNX Momentics: GoogleMock - 返回有价值,在函数中返回 void 错误
- 为什么新表达式可以正确生成指针类型,即使它应该返回 void*?
- 如何声明接受字符串、返回void的闭包的类型
- void *function() 是指向函数的指针还是返回 void* 的函数?
- return 语句,该语句调用在返回 void 的函数中返回 void 的函数
- GCC 9.1 返回 void& 作为显式析构函数调用的结果类型。这是一个错误吗?
- 分配运算符过载:返回void与返回参考参数
- 为什么平行std :: for_each返回void
- 传递返回 void * 作为参数的函数
- 如何验证 LLVM "ret"指令是否返回 void?
- 返回 void 或对自我的引用
- CRTP和返回void的方法*
- 为什么不允许虚方法返回 void 指针
- 为什么 std::fstream 返回 void 而不是 bool
- 重载运算符 = 返回 void 是否不可能成为复制赋值运算符
- C++:从void函数返回void函数的返回值
- 将返回void的函数传递给接受void的函数
- 返回 void 的模板函数
- 带有值的递归阶乘错误返回语句,在函数中返回 'void' [-fallowive]
- 从方法返回 void 以防止执行