При возврате указателя, что вернуть, если он не найден? C ++ - PullRequest
2 голосов
/ 12 ноября 2009

Я не уверен, что вернуть по умолчанию?

myDrugs является частным vector<Drug*> контейнером

Drug* DrugDealer::getFirstDrugInSack(DrugType drugtobuy)
{
    for (int i = 0; i < myDrugs.size(); i++)
    {
        if (myDrugs[i]->getType() == drugtobuy)
            return myDrugs[i];
    }

    return 0; // is this right?
}

Так что я бы назвал это так:

Drug *d = DrugDealer->getFirstDrugInSack(DrugType::Weed);
if (d != 0)
    // do something
else
    // onose?

Или есть лучший способ сделать это?

Ответы [ 7 ]

13 голосов
/ 12 ноября 2009

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

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

Если исключительное обстоятельство - не найти значение, и это указывает на то, что что-то не так, возможно, лучше использовать один из следующих подходов:

  • Выдает исключение .
  • Утверждение в сочетании с возвратом NULL. Самостоятельное утверждение обычно не рекомендуется, так как они (обычно) скомпилированы из сборок Release.

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

6 голосов
/ 12 ноября 2009

Некоторые люди предпочитают NULL 0. Вы также можете вызвать исключение.

4 голосов
/ 12 ноября 2009

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

bool DrugDealer::getFirstDrugInSack(DrugType drugtobuy, Drug** out)
{
    for (int i = 0; i < myDrugs.size(); i++)
    {
        if (myDrugs[i]->getType() == drugtobuy) {
           *out = myDrugs[i];
           return true;
        }

    }

    return false;
}

Вызов:

Drug* d;
if (dealer->getFirstDrugInSack(dragType, &d)) {
  // Found it, use it
}
1 голос
/ 12 ноября 2009

Я бы сказал, что у вас есть три варианта:

  1. возврат 0
  2. сгенерировать исключение
  3. использовать шаблон объекта Null

1) Имеет недостаток, который вы должны проверить на 0, если вы хотите избежать исключений. Это не тот путь, если вы пишете современный код на C ++, так как он делает код нестабильным (много if) и исключения делают код медленным, если случай, когда 0 возвращается с маловероятной вероятностью (тогда это не совсем исключение ;-))

2) То же самое, только путь, если ситуация маловероятна

3) Это заставит код работать во всех случаях, только если вам нужно проверить, есть ли наркотики или нет, вы должны сравнить с определенным NullObject, а не с 0. Это также может быть решено с помощью std::shared_ptr (который стал частью новой стандартной библиотеки C ++, если у вас более старый STL, вы можете использовать boost::shared_ptr, это шаблонный класс только для заголовков)

К вашему сведению: я собрал шаблоны проектирования, которые смог найти, и поместил их в список с возможностью просмотра http://www.color-of-code.de/index.php?option=com_content&view=article&id=68:software-patterns&catid=43:design&Itemid=66 Есть ссылки на википедию для записей, которые я могу найти.

РЕДАКТИРОВАТЬ: Здесь ссылка только для шаблона нулевого объекта: http://en.wikipedia.org/wiki/Null_Object_pattern

1 голос
/ 12 ноября 2009
Drug *myDrug = NULL;
In the loop, myDrug = myDrugs[i] followed by break;
and return myDrug.
0 голосов
/ 12 ноября 2009

другая опция, которую вы можете использовать - это возвращение NullObject

return Drug :: NullDrug;

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

хотя обычно я бы пошел с возвращением 0;

хорошо

обычно я бы использовал умные ptrs.

0 голосов
/ 12 ноября 2009

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

...