2

我不确定默认返回什么?

myDrugs是一个私有vector<Drug*>容器

Drug* DrugDealer::getFirstDrugInSack(DrugType drugtobuy)
{
    for (int i = 0; i < myDrugs.size(); i++)
    {
        if (myDrugs[i]->getType() == drugtobuy)
            return myDrugs[i];
    }

    return 0; // is this right?
}

所以我会这样称呼它:

Drug *d = DrugDealer->getFirstDrugInSack(DrugType::Weed);
if (d != 0)
    // do something
else
    // onose?

还是有更好的方法来做到这一点?

4

7 回答 7

12

我想说这取决于函数是否期望找到值,这取决于你的函数的定义和内聚性,以及它为客户端代码提供的合约类型。

如果找不到该值是可以接受的,我会说在这种情况下返回 NULL 指针是有效的,可以向客户端代码指示找不到该值。

如果在特殊情况下找不到值并且这表明存在问题,那么以下方法之一可能会更好:

  • 抛出异常
  • 断言与返回 NULL 一起使用。通常不建议单独断言,因为它们(通常)是从 Release 版本中编译出来的。

在您的情况下,我会说返回 NULL 是可以接受的,但如上所述,这会因每种情况而变化,并且此处没有适用的特定“经验法则”。

于 2009-11-12T00:07:41.720 回答
6

有些人更喜欢 NULL 而不是 0。您也可以引发异常。

于 2009-11-12T00:06:02.613 回答
4

返回 NULL 是可以的。您还可以考虑将指向指针的指针作为参数传递并返回布尔值,如果找到则返回 true,否则返回 false:

bool DrugDealer::getFirstDrugInSack(DrugType drugtobuy, Drug** out)
{
    for (int i = 0; i < myDrugs.size(); i++)
    {
        if (myDrugs[i]->getType() == drugtobuy) {
           *out = myDrugs[i];
           return true;
        }

    }

    return false;
}

来电:

Drug* d;
if (dealer->getFirstDrugInSack(dragType, &d)) {
  // Found it, use it
}
于 2009-11-12T00:08:18.087 回答
1
Drug *myDrug = NULL;
In the loop, myDrug = myDrugs[i] followed by break;
and return myDrug.
于 2009-11-12T00:05:29.183 回答
1

我会说你有三个选择:

  1. 返回 0
  2. 抛出异常
  3. 使用 Null 对象模式

1)如果你想避免异常,你必须测试 0 的缺点。如果您编写现代 C++ 代码,这不是要走的路,因为它会使代码跳跃(很多 if),如果返回 0 的情况不太可能(那么它不是真正的),异常会使代码变慢例外 ;-) )

2)同样的事情,只有在情况不太可能的情况下才能走

3)这将使代码在所有情况下都可以工作,只有在您必须检查是否有药物的情况下,您必须与定义的 NullObject 进行比较,而不是与 0 进行比较。这也可以通过使用来解决std::shared_ptr(这已成为新的 C++ 标准库的一部分,如果你有旧的 STL,你可以使用boost::shared_ptr,它是一个只有头的模板类)

仅供参考:我收集了我能找到的设计模式并将它们放入一个可概览的列表 http://www.color-of-code.de/index.php?option=com_content&view=article&id=68:software-patterns&catid=43:design&Itemid=66中。我能找到的条目有指向维基百科的反向链接。

编辑:这里只有空对象模式的链接:http://en.wikipedia.org/wiki/Null_Object_pattern

于 2009-11-12T00:15:19.010 回答
0

是的,这没关系。如果没有对象的情况不经常发生,并且处理这些对象的代码变得复杂,请考虑使用异常。

于 2009-11-12T00:07:02.517 回答
0

您可以使用的另一个选项是返回 NullObject

返回药物::NullDrug;

基本上一个被认为是“无效”的有效药物对象意味着如果你使用它,它就不会破裂。

虽然通常我会返回 0;

好,

通常,我会使用智能 ptrs。

于 2009-11-12T00:13:04.190 回答