C++: Возвратите ПУСТОЙ УКАЗАТЕЛЬ вместо структуры

У меня есть структура Foo. В псевдокоде:

def FindFoo:
   foo = results of search
   foundFoo = true if a valid foo has been found  

   return foo if foundFoo else someErrorCode

Как я могу выполнить это в C++?

Отредактированный для удаления многочисленных погрешностей.

9
задан Doro 3 December 2015 в 13:51
поделиться

8 ответов

Объекты C ++ никогда не могут быть пустыми или пустыми. Указатели могут содержать значение нулевого указателя, указывающее, что они ни на что не указывают.

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

Я бы не рекомендовал пытаться выучить C ++ на знаниях других языков, вы навредите себе. Возьмите хорошую книгу для начинающих , это лучший способ учиться.

13
ответ дан 4 December 2019 в 08:50
поделиться

Вызвать исключение. Вот для чего они нужны.

4
ответ дан 4 December 2019 в 08:50
поделиться

Вы можете изучить boost :: optional и посмотреть, соответствует ли он вашим потребностям. Однако:

return foo if foundFoo else someErrorCode

Это заставляет меня думать, что вам может быть лучше выбросить исключение, если вы не найдете foo.

3
ответ дан 4 December 2019 в 08:50
поделиться

Невозможно найти foo действительно в исключительной ситуации? Тогда выбросьте исключение. Ожидаете, что не найдете foo? Пусть функция вернет код ошибки и передаст foo через параметр ссылки, где foo будет действительным, только если функция не вернет ошибку.

1
ответ дан 4 December 2019 в 08:50
поделиться

Это тоже не работает в C #. Вы должны вернуть указатель на Foo.

1
ответ дан 4 December 2019 в 08:50
поделиться

Один из способов сделать это - вернуть указатель на foo:

public Foo* findFoo()
{
    return fooFound ? new fooResult() : NULL;
}

Другая возможность определить NullFoo ], возможно, как struct , расширяющая Foo пустой реализацией. Для получения дополнительной информации о последней идее вы можете прочитать о шаблоне Null Object Pattern .

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

1
ответ дан 4 December 2019 в 08:50
поделиться

Вы также не можете сделать это на C # - вам нужно будет вернуть new Foo () , а не null , чтобы компилятор был доволен.

То же самое в случае C ++ - вам нужно создать экземпляр структуры, если вы собираетесь возвращать по значению. Если нет, вы хотите выполнить возврат по указателю (в этом случае вы должны new или вернуть указатель на один, выделенный другим способом, что вносит в уравнение беспорядочную семантику передачи прав собственности).

РЕДАКТИРОВАТЬ: на основе вашего обновления. Кажется, вы хотите вернуть либо значение, либо мета-значение «null», которое указывает «не найдено». Вы можете сделать это несколькими способами:

  1. throw в случае сбоя, в противном случае безоговорочно вернуть значение
  2. вернуть указатель - но это оставляет ответственность за удаление его в воздух, если это не что-то, что будет оставаться в памяти надолго
  3. , оберните его в [шаблонный] объект-оболочку, который обрабатывает условия так же, как .NET Nullable (I позволю кому-нибудь вмешаться с правильным ОБНОВЛЕНИЕ: @Mike Seymour говорит, что boost :: optional )
  4. использует шаблон Null Object, чтобы вернуть соответствующее значение, которое работает правильно, когда обрабатывается как действительный результат на стороне клиента
0
ответ дан 4 December 2019 в 08:50
поделиться

Это невозможно в C ++ без обращения к указателям или библиотечному решению вне стандартной библиотеки. (Boost не является частью стандартной библиотеки, это решение сторонних производителей.)

В C # вы можете использовать Nullable .

В отличие от комментария Билли, структуры являются типами значений, а не ссылочными типами, и Nullable может применяться к любому типу значения, а не только к встроенным. Следующее компилируется отлично:

struct Test {
    int Blah;
}
void Main() {
    System.Nullable<Test> proof;
}
1
ответ дан 4 December 2019 в 08:50
поделиться
Другие вопросы по тегам:

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