【问题标题】:How to handle optional parameter + optional return value如何处理可选参数+可选返回值
【发布时间】:2015-01-07 13:45:35
【问题描述】:

问题如下:我有一个类,它封装了某种容器(即地图),我可以通过对象 ID 查询该容器。该类还封装了第二个容器,该容器保存属于对象的附加数据(即矩阵)。 我班级的客户应该有可能查询对象并决定他是否也希望返回附加数据,即以这种方式:

ObjectData objData;
Object obj = myClass.getObject(objectID, &objData);

但是,如果客户端请求附加数据,但他查询的对象没有链接到它的附加数据,那么客户端应该能够告诉这一点。 IE。如果我的函数是这样工作的:

Object MyClass::getObject(ObjectID oID, ObjectData* objData)
{
    // ...
    if(objData && this->hasObjectData(oID))
      objData = this->getObjectData(oID);
}

并且客户端以上述方式调用它,getObject 函数识别出所查询的对象没有附加数据,并将保持传递的 objData 指针不变。然后客户端发现自己有一个默认构造的 ObjectData 对象,并且不知道它是默认构造的还是由 getObject 函数作为参数返回值返回的。

在我的脑海中,我只能想到或多或少丑陋的解决方案,例如在堆上分配数据,以便用户可以取回空指针或以某种方式向函数调用添加标志。可能更好的设计是完全单独地查询 objectData 但上面会很好而且很容易所以我想知道是否有一个优雅的解决方案仍然可以以这种方式进行。

【问题讨论】:

  • Boost Optional怎么样?
  • 我不认为堆分配/空指针解决方案特别难看。您也许可以使用智能指针使其更安全。最后,我更喜欢你的第二个解决方案。您还可以更改 getObjectData 以引用 ObjectData 并返回一个布尔值,说明数据是否已写入。这有点紧凑。
  • 我不认为你写的代码能做你想做的事。您想提供任何附加数据的副本还是指针?假设你想要一个副本,它可能应该是 *objData = this->getObjectData(oID); 如果你想提供一个指针,你需要传递类似 ObjectData*& 的东西。

标签: c++ optional-parameters


【解决方案1】:
getObject(objectID, &objData);

通过这种方式使用getObject,您将赋予它两个职责。首先是准备好对象,其次是检查是否可以使用其他信息加载它。我建议将其分为两部分(方法)。

obj = getObject(objectID);  // get the object based on definite 
                            // info i.e 1st container.
if(obj.isMatrixValid)
    obj.setMatrixData();

因此,您在这里将职责分为两种方法。但是,一个缺点是您必须记住在创建后更新object

【讨论】:

    【解决方案2】:

    那么更好的设计可能是完全单独地查询 objectData

    是的。

    getObject 的职责太多。

    但以上内容会很简单

    如果客户端实际上并不关心额外的对象数据,那么这会更好更容易:

    Object obj = myClass.getObject(objectID)
    

    然后,对于 objectData 的单独查询,您有几个选项。您可以强制客户端在查询之前检查您是否有 objectData:

    if (myClass.hasObjectData()) {
        ObjectData data = myClass.getObjectData();
    }
    

    或者你可以返回一个指针。如果客户端不需要拥有ObjectData,您可以只返回一个原始指针。如果客户端需要拥有ObjectData,我认为在堆上分配并返回智能指针没有什么难看的:

    std::unique_ptr<ObjectData> data = myClass.getObjectData();
    if (data) {
        // do something with data...
    }
    

    或者以类似的方式,您可以使用Boost.Optional

    如果没有额外的 objectData,您也可以考虑 Null Object pattern 并返回 NullObjectData 对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-14
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多