Как Вы “повреждаетесь” из функции?

Учитывая функцию, которая возвращает значение, действительно ли возможно выйти из функции, учитывая определенное условие, ничего не возвращая? Если так, как можно выполнить это?

Пример:

int getNumber ()
{ 
    . . . 
}

Поэтому скажите, что Вы находитесь в этой функции. Существует ли способ выйти из него без него делающий что-нибудь?

8
задан Brandon 17 February 2010 в 07:37
поделиться

13 ответов

У вас есть два варианта: вернуть что-то или выбросить .

int getNumber() 
{
    return 3;
}

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

Если вы бросаете , вы должны поймать того типа, который вы бросили.

int maint(int argc, char ** argc)
{
     try
     {
           getNumber();
     }
     catch(string std)
     {
          //Your code will execute here if you throw
     }
 }
15
ответ дан 5 December 2019 в 04:36
поделиться

Вы можете уйти с возвращением; без возвращаемого значения. Компилятор выдаст предупреждение, но не ошибка.

НО , с какой стати вы вообще об этом думаете? Чего вы пытаетесь достичь?

И как выглядит вызывающий код? Если это 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
16
ответ дан 5 December 2019 в 04:36
поделиться

возможность просмотра заголовков ограничена в нескольких браузерах, поэтому флэш-память имеет проблемы с передачей информации. это в основном обвиняется в настройках браузера, но мне еще предстоит найти то, где он на самом деле работает. вывод события состояния .

я сдался и заставил файл напечатать код ответа в моих проектах, не замечательно (и несколько победив точку), но, кажется, работает.

-121--5085993-

В окнах функции non-_r безопасны для потоков, поскольку они используют локальное место хранения потоков для буфера. См., например, http://msdn.microsoft.com/en-us/library/bf12f0hc (VS.80) .aspx

-121--2938579-

Для плавающих и двойных типов существует альтернатива, но не для типов 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. Каждое условие на валу будет верным.

3
ответ дан 5 December 2019 в 04:36
поделиться

Вы также можете вернуть класс / структуру с некоторым магическим преобразованием, которое будет полезно для ваших особых нужд.

Пример из реальной жизни: однажды мне действительно пришлось вернуть две части информации в одном и том же возвращаемом значении, значение, чтобы сообщить, было ли сообщение окна полностью обработано, и значение, которое будет возвращено для него, если обработка уже завершена. . Поэтому я собрал все в такой класс:

//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 / something; , если сообщение было полностью обработано и у меня уже было возвращаемое значение. Вызывающий, со своей стороны, мог бы просто сделать

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

. Если у вас более сложные потребности, вы также можете рассмотреть возможность использования boost :: tuple.

1
ответ дан 5 December 2019 в 04:36
поделиться

Простое решение:

boost::optional<int> getNumber( )
{
  // May now return an int, or may return nothing.
}
8
ответ дан 5 December 2019 в 04:36
поделиться

Сделайте требованием для пользователя сначала проверить, что очередь не пуста (обеспечьте средства для этого).

Затем вы можете:

  • ничего не проверять и просто вызвать неопределенное поведение (доступ к базовым данным, как будто они есть) - это вина пользователя
  • проверить и выбросить исключение
  • assert (результат не определен с NDEBUG)

Проверить, а затем вызвать неопределенное поведение (возврат произвольного значения) - это худшее, что можно сделать. Вы получаете и накладные расходы времени выполнения проверки, и вызывающему ничего не остается, так как результат все равно не определен.

3
ответ дан 5 December 2019 в 04:36
поделиться

Альтернативой исключений является возврат кода состояния:



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>
2
ответ дан 5 December 2019 в 04:36
поделиться

Вы можете создать указанное исключение и соответствующим образом его перехватить.

1
ответ дан 5 December 2019 в 04:36
поделиться

Вы можете создать исключение . Вы ничего не вернете, но вам придется перехватить исключение, чтобы определить, что делать дальше (вы всегда можете проглотить исключение и ничего не делать для достижения желаемого).

0
ответ дан 5 December 2019 в 04:36
поделиться

Вы можете использовать setjmp / longjmp (см. http://en.wikipedia.org/wiki/Setjmp.h ), но с точки зрения разработки программного обеспечения лучше использовать исключения или коды ошибок, как упоминалось здесь другими.

-1
ответ дан 5 December 2019 в 04:36
поделиться

Редизайн вашего метода, вероятно, будет правильным, если вам нужно выйти из функции, которая должна возвращать значение ... или вы можете просто вернуть значение "ошибки" какой-то.

0
ответ дан 5 December 2019 в 04:36
поделиться

В C ++ функция должна возвращать значение (тип значения, ссылка или адрес), если оно указано в объявлении / определении функции.

0
ответ дан 5 December 2019 в 04:36
поделиться

Каков ваш реальный сценарий использования?

Если вам действительно нужно ничего не возвращать и прервать нормальное выполнение функции, вы можете бросить исключение.

Вы также можете вернуть что-то, что вызывающая сторона интерпретирует как ошибку (или "ничего не возвращено").

Каким бы ни было ваше решение, вызывающая сторона должна отдельно обработать случай "ничего не возвращается", например, поймать исключение или проверить возвращаемое значение.

0
ответ дан 5 December 2019 в 04:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: