如何处理可选参数+可选return值
How to handle optional parameter + optional return value
问题如下:我有一个 class,它封装了我可以通过对象 ID 查询的某种容器(即地图)。 class 还封装了第二个容器,其中包含属于对象的附加数据(即矩阵)。
我的 class 的客户端应该可以查询对象并决定他是否也想要 returned 的附加数据,即以这种方式:
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 函数 returned 作为参数 return 值。
在我的脑海中,我只能想到或多或少丑陋的解决方案,例如在堆上分配数据,以便用户可以取回空指针或以某种方式向函数调用添加标志。可能更好的设计是完全单独查询 objectData,但上面的方法很好也很容易,所以我想知道是否有一个优雅的解决方案仍然以这种方式进行。
getObject(objectID, &objData);
通过这种方式使用 getObject
,您赋予了它两个职责。首先是准备好对象,其次是检查是否可以加载附加信息。我建议将其分为两部分(方法)。
obj = getObject(objectID); // get the object based on definite
// info i.e 1st container.
if(obj.isMatrixValid)
obj.setMatrixData();
因此,您在这里将责任分为两种方法。但是,一个缺点是您必须记住在创建后更新 object
。
Probably a better design would then be to query objectData completely separately
是。
getObject
责任太多了。
but the above would be nice and easy
如果客户端实际上并不关心额外的对象数据,那么这会更好更容易:
Object obj = myClass.getObject(objectID)
然后对于 objectData 的单独查询,您有几个选择。您可以强制客户端在查询之前检查您是否有 objectData:
if (myClass.hasObjectData()) {
ObjectData data = myClass.getObjectData();
}
或者您可以 return 指针。如果客户端不需要拥有 ObjectData
你可以只 return 一个原始指针。如果客户端需要拥有 ObjectData
我不认为在堆上分配和 return 使用智能指针有什么不好的:
std::unique_ptr<ObjectData> data = myClass.getObjectData();
if (data) {
// do something with data...
}
或者以类似的方式,您可以使用 Boost.Optional。
如果没有额外的对象数据,您也可以考虑 Null Object pattern 和 return 一个 NullObjectData
对象。
问题如下:我有一个 class,它封装了我可以通过对象 ID 查询的某种容器(即地图)。 class 还封装了第二个容器,其中包含属于对象的附加数据(即矩阵)。 我的 class 的客户端应该可以查询对象并决定他是否也想要 returned 的附加数据,即以这种方式:
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 函数 returned 作为参数 return 值。
在我的脑海中,我只能想到或多或少丑陋的解决方案,例如在堆上分配数据,以便用户可以取回空指针或以某种方式向函数调用添加标志。可能更好的设计是完全单独查询 objectData,但上面的方法很好也很容易,所以我想知道是否有一个优雅的解决方案仍然以这种方式进行。
getObject(objectID, &objData);
通过这种方式使用 getObject
,您赋予了它两个职责。首先是准备好对象,其次是检查是否可以加载附加信息。我建议将其分为两部分(方法)。
obj = getObject(objectID); // get the object based on definite
// info i.e 1st container.
if(obj.isMatrixValid)
obj.setMatrixData();
因此,您在这里将责任分为两种方法。但是,一个缺点是您必须记住在创建后更新 object
。
Probably a better design would then be to query objectData completely separately
是。
getObject
责任太多了。
but the above would be nice and easy
如果客户端实际上并不关心额外的对象数据,那么这会更好更容易:
Object obj = myClass.getObject(objectID)
然后对于 objectData 的单独查询,您有几个选择。您可以强制客户端在查询之前检查您是否有 objectData:
if (myClass.hasObjectData()) {
ObjectData data = myClass.getObjectData();
}
或者您可以 return 指针。如果客户端不需要拥有 ObjectData
你可以只 return 一个原始指针。如果客户端需要拥有 ObjectData
我不认为在堆上分配和 return 使用智能指针有什么不好的:
std::unique_ptr<ObjectData> data = myClass.getObjectData();
if (data) {
// do something with data...
}
或者以类似的方式,您可以使用 Boost.Optional。
如果没有额外的对象数据,您也可以考虑 Null Object pattern 和 return 一个 NullObjectData
对象。