Действительно ли это - хороший дизайн к возвращаемому значению параметром?

bool is_something_ok(int param,SomeStruct* p)
{
    bool is_ok = false;

    // check if is_ok

    if(is_ok)
       // set p to some valid value
    else
       // set p to NULL
    return is_ok;
}

эта функция возвращает true и установила p на допустимое значение, если "что-то в порядке", иначе возвращают false и устанавливают p в NULL

Это - хороший или плохой дизайн? лично, я чувствую себя неловко, когда я использую его. Если нет никакого документа и комментария, я действительно, Дон знает, как использовать его.

BTW:Is там некоторая авторитетная книга/статья о дизайне API?

22
задан Phong 16 March 2010 в 07:48
поделиться

8 ответов

Поскольку вы пометили вопрос как C ++, а не C, я предлагаю вам:

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

Но это лишь некоторые общие подсказки. Лучший способ всегда зависит от конкретной проблемы ...

13
ответ дан 29 November 2019 в 05:31
поделиться

Я склонен это делать. Альтернативой в примере является либо кодирование двух вещей в одно возвращаемое значение (например, использование NULL в качестве специального значения), либо возврат структуры.

Кодирование двух вещей иногда может быть невозможным и немного подвержено ошибкам. Возвращение конструкции — это много дополнительной работы и беспорядка. Поэтому я склонен делать то, что сделали вы. Я склонен предполагать, что «сырые» указатели и ссылки в списке параметров предназначены для возврата значений, и они были бы «const», если бы они были только для передачи данных.

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

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

2
ответ дан 29 November 2019 в 05:31
поделиться

Я бы сказал, это зависит от обстоятельств. Насколько дорого стоит копировать конструкцию вашего типа? Можете ли вы написать свою функцию RVO -дружелюбной? По крайней мере, пока у нас не будет C ++ 0x с ссылками на rvalue , я бы рекомендовал не возвращать «дорогие» типы (такие как std :: vector ). , а лучше передать их как ссылки, например используйте:

void split(const std::string &txt, char sep, std::vector<std::string> &out);

, а не:

std::vector<std::string> split(const std::string &txt, char sep);

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

2
ответ дан 29 November 2019 в 05:31
поделиться

Я думаю вернуть NULL, если что-то не в порядке, и действительный SomeStruct, если в этом случае лучше

SomeStruct* is_something_ok(int param);

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

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

1
ответ дан 29 November 2019 в 05:31
поделиться

Зависит от того, как вы хотите обрабатывать «ошибки».

Например, возьмем стандартную функцию atoi. Он преобразует строку в целое число, но если строка не содержит числа, что она должна вернуть? В этом случае среда выполнения C / C ++ установит глобальную переменную errno. Альтернативой было бы создание исключения.

Лично мне не нравятся обе эти альтернативы. Поэтому, если я обычно использую следующие правила:

  • Есть ли в диапазоне возможных возвращаемых значений значение, которое можно использовать для указывает на ошибку, и возможно ли у меня только 1 "вид" ошибки? В таких случаях я использую возвращаемое значение, чтобы указать на ошибку. Например. такая функция, как FindEmployee, может просто вернуть NULL, если сотрудник не найден.
  • Если все возможные значения могут быть возвращены функцией (как в примере с atoi), используйте выходной аргумент для возвращаемого значения и позвольте функции возвращать логическое значение. Если у вас более 1 возможного случая ошибки, верните перечисление, которое указывает тип ошибки (или успеха), которая произошла.
3
ответ дан 29 November 2019 в 05:31
поделиться

Вы можете сделать следующее:

bool is_something_ok(int param,SomeStruct* p);

или

// return NULL if the operation failed.
Somestruct* do_work(int param);

Трудно сказать, хорош или плох дизайн/API, нет ничего черного или белого ... (серый?!?!?)

Вы должны выбрать API/стандарт, с которым вам будет проще кодить. И будьте последовательны, если вы выбрали первый тип метода, делайте это и для остальной части вашего проекта.

Не забывайте также документировать свой код, так будет проще понять, как использовать ваш API.

1
ответ дан 29 November 2019 в 05:31
поделиться

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

0
ответ дан 29 November 2019 в 05:31
поделиться

Я бы предложил возвращать непосредственно Result-Type, как например:

SomeStruct doSomething(int param) {...}

и бросать исключение в случаях, когда функция не может справиться (tux21b уже упоминал этот способ). В качестве альтернативы можно возвращать два типа с помощью std::pair без выброса исключения, как например:

pair<SomeStruct, bool> doSomething(int param) {...}

И третье, мне нравится объявлять выходные параметры как указатели, а не как ссылки (как вы упомянули), потому что в вызывающем коде я вижу разницу между входными и выходными параметрами. Дана функция:

void doSomething(const Somestruct& in, Somestruct* out) {...}

Тогда в вызывающем коде видно (не глядя на объявление функции), что является входным, а что выходным параметром (если я правильно применяю эту концепцию).

SomeStruct a;
SomeStruct b;
doSomething(a, &b); // you see a is input, b is output
1
ответ дан 29 November 2019 в 05:31
поделиться
Другие вопросы по тегам:

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