你如何“打破”一个功能?

时间:2010-02-17 07:37:05

标签: c++

给定一个返回值的函数,是否可以在给定某个条件的情况下退出函数而不返回任何内容?如果是这样,你怎么能做到这一点?

示例:

int getNumber ()
{ 
    . . . 
}

所以说你在这个职能部门。有没有办法退出它而不做任何事情?

13 个答案:

答案 0 :(得分:16)

可能会逃脱没有返回值的return;。编译器会发出警告,但可能不会出错。

但是,你到底为什么会考虑这个?你想要实现什么目标?

调用代码是什么样的?如果它是int someVar = getNumber();那么someVar的值是未定义的(这是一个坏事)。

听起来我想要返回两条信息,其中一条告诉你另一条是否有效。

尝试类似

的内容
bool GetNumber(int * outputNumber)
{
   if ....
   {
      *outputNumber = ...;
      return true;
   }  
   else
   {
      return false; // contents of outputNumber are undefined
   }
}

int number;
bool isNumberValid;
isNumberValid = GetNumber(&number);
if (isNumberValid)
    ... do something with number

答案 1 :(得分:15)

您有两种选择:return某事或throw

int getNumber() 
{
    return 3;
}

int getNumber() 
{
    throw string("Some Var");
}

如果您throw,则必须catch您投掷的类型。

int maint(int argc, char ** argc)
{
     try
     {
           getNumber();
     }
     catch(string std)
     {
          //Your code will execute here if you throw
     }
 }

答案 2 :(得分:8)

简单的解决方案:

boost::optional<int> getNumber( )
{
  // May now return an int, or may return nothing.
}

答案 3 :(得分:3)

对于float和double,有一种替代方法,但不适用于int类型。

#include <limits>

double Get()
{
  // no valid return value
  return std::numeric_limits<double>::quiet_NaN();
}

double val = Get();
if(val != val) {
  // Retrieved no valid return value 
}
else {
  // No NaN retrieved
}

使用NaN时要小心。 val上的每个条件都是真的。

答案 4 :(得分:3)

要求用户首先检查队列是否为空(提供相应的方法)。

然后你可以:

  • 不检查任何内容,只是调用未定义的行为(访问底层数据,就像它在那里一样) - 这是用户的错误
  • 检查并抛出异常
  • 断言(结果未使用NDEBUG定义)

检查然后调用未定义的行为(返回任意值)是最糟糕的事情。您同时获得了检查的运行时开销,并且调用者并不明智,因为结果仍未定义。

答案 5 :(得分:2)

异常的替代方法是返回状态代码:

SomeStatusCode YourFunc(int &returnValue) { ... returnValue = SomeValue; return SomeStatusCode.Successful; ... return SomeStatusCode.Fail; } //in main func if(YourFunc(retValue)==SomeStatusCode.Successful) // work with retValue else // nothing to do, show error, etc. </code>

答案 6 :(得分:1)

您可以抛出指定的异常并相应地捕获它。

答案 7 :(得分:1)

你也可以返回一个带有魔术转换的类/结构,这对你的特殊需要很有用。

现实生活中的例子:一旦我实际上在同一个返回值中返回两条信息,一个值报告窗口消息是否已经完全处理,如果处理已经完成则返回值。所以我在这样的课程中打包了所有内容:

//This class is used to carry a return value for a window message and a value that indicates if the
//message has already been completely processed
class MessageReturnValue
{
public:
    LRESULT returnValue;
    bool processed;
    MessageReturnValue()
    {
        processed=false;
        returnValue=FALSE;
    };
    MessageReturnValue(LRESULT ReturnValue)
    {
        processed=true;
        returnValue=ReturnValue;
    };
    MessageReturnValue(bool Processed)
    {
        returnValue=FALSE;
        processed=Processed;
    };
    inline operator bool()
    {
        return processed;
    };
    inline operator LRESULT()
    {
        return returnValue;
    };
};

这允许我在一个函数中只执行return false;,如果邮件仍然需要处理,则返回MessageReturnValue;如果邮件已经完全处理并且我已经返回,则return TRUE/15/whatever;值。呼叫者可以简单地执行

LRESULT MyWndProc(/* blah blah blah */)
{
    MessageReturnValue ret = MyFunction(/* blah blah blah */);
    if(!ret)
    {
        /* process the message */
        return /* something */;
    }
    else
        return (LRESULT)ret;
}

如果您有更复杂的需求,您还可以考虑使用boost :: tuple。

答案 8 :(得分:0)

在C ++中,如果在函数声明/定义中指定了一个函数,函数必须返回一个值(值类型,引用或地址)。

答案 9 :(得分:0)

你可以抛出一个exception。你不会返回任何东西,但是你必须抓住异常以确定下一步该做什么(你总是可以吞下异常而无法实现你想要的任何东西)。

答案 10 :(得分:0)

如果你需要打破一个意味着返回一个值的函数,你的方法可能会重新设计......或者你可以简单地返回某种类型的“错误”值。

答案 11 :(得分:0)

您的实际用例是什么?

如果你真的不需要返回任何内容并终止正常的函数执行,你可以抛出exception

您还可以返回调用者将其解释为错误(或“未返回任何内容”)的内容。

无论您的解决方案是什么,呼叫者都需要单独处理“没有返回”的情况,例如:捕获异常或检查返回的值。

答案 12 :(得分:-1)

您可以使用setjmp / longjmp(请参阅http://en.wikipedia.org/wiki/Setjmp.h),但从软件工程的角度来看,最好使用其他人提到的异常或错误代码。