2013-05-29 3 views
2

У меня есть класс с функцией Load(), например.C++ 11 код ошибки возврата из функции

class DB { 
private: 
    pt_db *db; 
public: 
    DB(const char *path); 
    Write(const char *path); 
    int Load(const char *path); 
}; 

И я хочу, чтобы вернуть некоторые из состояния Load() функции в зависимости от переданного аргумента.

Например:

Load(<correct path to the file with valid content>) // return 0 - success 
Load(<non-existent path to file>) // return 1 
Load(<correct file path, but the content of the file is wrong>) // return 2 

Но также я беспокоиться о:

  1. Тип безопасности - я имею в виду, я хочу, чтобы вернуть какой-то объект, который может быть использован только в качестве кода состояния.

    int res = Load(<file path>); 
    
    int other = res * 2; // Should not be possible 
    
  2. Использовать только предопределенные значения. С int я могу вернуться, по ошибке, некоторые другие состояния, как return 3 (давайте предложить что-то не так произошло в Load() функции), и если я не ожидаю этот код ошибки будет передано:

    int res = Load(<file path>); 
    
    if(res == 1) {} 
    
    else if (res == 2) {}; 
    
    ... 
    
    // Here I have that code fails by reason that Load() returned non-expected 3 value 
    
  3. Использования лучшим C++ 11 об этом.

Может ли кто-нибудь помочь?

+4

Будет ли ['enum class'] (http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerations) сделать это? – BoBTFish

+2

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

+0

Я просто хочу знать некоторые возможные решения. Почему у C++ 11 есть std :: error_code? Также я предлагаю, чтобы этот код можно было использовать в C-коде, а C не может обрабатывать исключения. – likern

ответ

3

Перечисления будет хорошим способом вернуть статус, например:

class Fetcher{ 
public: 
enum FetchStatus{ NO_ERROR, INVALID_FILE_PATH, INVALID_FILE_FORMAT }; 
private: 
FetchInfo info; 
public: 
FetchStatus fetch(){ 
    FetchStatus status = NO_ERROR; 
    //fetch data given this->info 
    //and update status accordingly 
    return status; 
} 
}; 

Другим способом было бы использовать исключения

class Fetcher{ 
private: 
FetchInfo info; 
public: 
void fetch(){ 
    if file does not exist throw invalid file path exception 
    else if file is badly formatted throw invalid file format exception 
    else everything is good 
} 

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

+5

и 'enum class' даже даст тип безопасности OP после ... – StoryTeller

+0

Существует также возможность добавить' __attribute __ ((warn_unused)) '(в gcc и clang как минимум) в результате функции, гарантирующей, что возврат код не игнорируется. К сожалению, исключения C++ не проверяются, поэтому все еще возможно получить что-то неправильно (есть RAII, но он защищает в основном от распределения ресурсов - могут быть более тонкие проблемы, вызванные завершенным кодом). –

+0

Является ли смешивание исключений и код ошибки приемлемой практикой? Например, исключение исключения из конструктора БД, и если 'Load()' fail возвращает код ошибки, так как в этом случае я просто не буду обновлять внутренние данные объекта и будет указывать на старые данные при создании объекта? – likern

Смежные вопросы