Kon*_*rad 8 c++ function pass-by-reference
让我们说我们有一个形式的功能:
const SomeObject& SomeScope::ReturnOurObject()
{
if( ! SomeCondition )
{
// return early
return ;
}
return ourObject;
}
Run Code Online (Sandbox Code Playgroud)
显然,上面的代码有一个问题,如果条件失败,那么我们就如何从这个函数返回一个问题.我的问题的关键是处理这种情况的最佳方法是什么?
sbi*_*sbi 24
这不是语法问题,而是设计问题.您必须指定ReturnOurObject()
在SomeCondition
true 时应返回的内容.这主要取决于该功能将用于什么.你还没有告诉我们.
根据设计问题,我看到了一些可能的语法方法:
SomeCondition
是客户无法处理的特殊情况,那将是合适的SomeCondition
应该总是持有,那就应该断言我可能会这样做:
const SomeObject& SomeScope::ReturnOurObject()
{
if( ! SomeCondition )
{
throw SomeException();
}
return ourObject;
}
const SomeObject *SomeScope::ReturnOurObjectIfPermitted()
{
return SomeCondition ? &ourObject : 0;
}
Run Code Online (Sandbox Code Playgroud)
也许还有:
bool SomeScope::CheckMode();
return SomeCondition;
}
Run Code Online (Sandbox Code Playgroud)
然后呼叫者有一些选择:
// 1 - "I know that I'm in the right mode"
myScope.ReturnOurObject().DoSomething();
// 2 - "I don't know whether I'm in the right mode, but I can cope either way"
if (SomeObject *myObject = myScope.ReturnOurObjectIfPermitted()) {
myObject->DoSomething();
} else {
DoSomethingElse();
}
// 2 - alternate version:
if (myScope.CheckMode()) {
SomeObject &myObject = myScope.ReturnOurObject();
myObject.DoSomething();
} else {
DoSomethingElse();
}
// 3 - "I don't know whether I'm in the right mode. If I'm not then
// I can't deal with it now, but some higher-level code can"
try {
// ... several calls deep ...
myScope.ReturnOurObject().DoSomething();
// ... several returns back ...
} catch (SomeException &e) {
DoSomethingElse();
}
Run Code Online (Sandbox Code Playgroud)
您根据前提条件设计一个函数的界面,即确定它可以完成其工作的责任.
如果是来电者的责任,那么他们需要有能力确保这一点.你可能想要检查,只是为了安全起见.当不满足所谓的"前置条件"时抛出异常会使它们更像是建议而不是条件,并且如果您不介意检查的运行时开销,它可以很好地工作.我通常对前置条件相当不宽容,所以实际上我可能会用断言替换条件异常,并记录不能在错误模式下调用该函数.这取决于调用者对模式的控制程度 - 显然,如果它随意改变(例如,如果"SomeCondition"是"UART上没有可用的字节")那么你需要一个非常不同的接口,如果它只是改变了当客户端代码调用某个函数来改变它时.
如果调用者没有责任让模式正确,那么您的界面不应该写出您的实现无法兑现的检查.在这种情况下,如果"预期"没有对象返回,则返回不应该是引用.除非(a)你可以发出一个特殊的"抱歉,它没有用"对象返回,调用者可以检查,或者(b)你很乐意在"预期"的情况下抛出异常.IMO(b)在C++中很少见.(a)通常不比返回空指针好,但偶尔也是如此.例如,返回一个空集合意味着"没有什么你可以在这里看到的"可能会导致一些非常干净的调用代码,如果DoSomethingElse()
是"什么也不做".因此,除了期望的职责外,界面还取决于预期的用例.
'ourObject'的生命周期是什么?它在哪里创建?
如果您需要提前返回而不触及/更新我们的对象,并且它存在于您返回的位置,我看不到返回对它的引用的问题.
如果你正在尝试通知存在错误,你可能不得不抛出异常而不是提前返回,因为你的函数同意的合同说它会返回对'SomeObject'的引用.
如果您要返回对临时的引用,则最好解决该问题...
我将返回一个布尔值并将对象引用作为参数传递给函数:
bool getObject(SomeObject& object)
{
if( condition )
return false;
object = ourObject;
return true;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您现在只有在函数返回true时才填充对象.
归档时间: |
|
查看次数: |
1058 次 |
最近记录: |