如何处理可选参数+可选返回值

时间:2015-01-07 13:45:36

标签: c++ optional-parameters

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

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

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

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

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

在我的脑海中,我只能想到或多或少的丑陋解决方案,比如在堆上分配数据,以便用户可以返回nullpointers或以某种方式为函数调用添加标志。可能更好的设计就是完全单独地查询objectData,但上面的内容会很简单,所以我想知道是否有一个优雅的解决方案仍然可以这样做。

2 个答案:

答案 0 :(得分:0)

getObject(objectID, &objData);

通过这种方式使用getObject,您将承担两项责任。第一个是准备对象,第二个是检查是否可以加载其他信息。我建议将其分为两部分(方法)。

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

所以,在这里你把责任分成两个方法。但是,一个缺点是您必须记住在创建后更新object

答案 1 :(得分:0)

  

可能更好的设计是完全单独查询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对象。