gpt4 book ai didi

c++ - 非 void 函数可能缺少返回值

转载 作者:行者123 更新时间:2023-11-28 01:30:37 27 4
gpt4 key购买 nike

我写了这段代码来检查一个节点是树中的左 child 还是右 child 。然而,从清洁的角度来看,我认为它没有得到妥善实现。

我的问题是,如果父指针为空,则返回默认值(如 false)是危险的,因为 false 意味着它是一个正确的 child 。但是,如果我希望它在没有警告的情况下进行编译,则此函数需要返回。作为解决方案,空投绝对是丑陋的。

我见过人们使用 assert(parent) 而不是 if,但我认为这也不好,因为 assert 是一个调试功能。

简而言之,实现这个功能有什么更好的想法?

bool isLeftChild() const {
if(parent){
if(this == (parent->left).get()){
return true;
}
else if(this == (parent->right).get()){
return false;
}
}
else throw;
}

最佳答案

清洁度最终是一个见仁见智的问题。你遇到的问题是这个函数的契约是什么。也就是说,如果在具有 NULL 父节点的节点上调用此代码,您是否希望它定义此代码的行为?

如果答案是肯定的,那么 throw 是完全有效的。很像 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 中,您可以将其表示为契约(Contract):

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)。

关于c++ - 非 void 函数可能缺少返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51688583/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com