Что добавить в класс C ++, оборачивающий библиотеку C? - PullRequest
3 голосов
/ 31 мая 2010

Мне нужно создать набор классов C++ для существующей библиотеки C.

Для многих объектов библиотеки C построение выполняется путем вызова чего-то вроде britney_spears* create_britney_spears() и противоположной функции void free_britney_spears(britney_spears* brit).

Если присвоение britney_spears не удается, create_britney_spears() возвращает NULL.

Насколько я знаю, это очень распространенная модель.

Теперь я хочу обернуть это в C++ класс.

//britney_spears.hpp

class BritneySpears
{
  public:

    BritneySpears();

  private:

    boost::shared_ptr<britney_spears> m_britney_spears;
};

А вот и реализация:

// britney_spears.cpp

BritneySpears::BritneySpears() :
  m_britney_spears(create_britney_spears(), free_britney_spears)
{
  if (!m_britney_spears)
  {
    // Here I should throw something to abort the construction, but what ??!
  }
}

Итак, вопрос в примере кода: Что я должен бросить, чтобы прервать конструктор?

Я знаю, что могу бросить почти все, но я хочу знать, что обычно делается. У меня нет другой информации о том, почему распределение не удалось. Должен ли я создать свой собственный класс исключений? Есть ли std исключение для таких случаев?

Большое спасибо.

Ответы [ 3 ]

5 голосов
/ 31 мая 2010

Вы не хотите получать исключение BritneyFailedToConstruct. По моему опыту, вы должны сохранять иерархии исключений как можно более плоскими (я использую один тип для каждой библиотеки). Исключение должно быть производным от std :: exception и каким-то образом должно содержать сообщение, которое доступно через std:; Exception virtual What () Затем вы бросаете его в свой конструктор:

throw MyError( "failed to create spears object" );

Ниже приводится объявление для класса исключений, который я использую в своей собственной служебной библиотеке:

class Exception : public std::exception {

    public:

        Exception( const std::string & msg = "" );
        Exception( const std::string & msg, int line,
                        const std::string & file );

        ~Exception() throw();

        const char *what() const throw();
        const std::string & Msg() const;

        int Line() const;
        const std::string & File() const;

    private:

        std::string mMsg, mFile;
        int mLine;
};

#define ATHROW( msg )\
{   \
    std::ostringstream os;  \
    os << msg               \
    throw ALib::Exception( os.str(), __LINE__, __FILE__  ); \
}   \

Макрос предназначен для удобного добавления имени файла и номера строки и обеспечения форматирования потока для сообщения. Это позволяет вам говорить такие вещи, как:

ATHROW( "britney construction failed - bad booty value of " << booty );
1 голос
/ 31 мая 2010

Я бы либо выбросил runtime_error ( ссылка ), либо объект вашего собственного класса, полученный из runtime_error.

1 голос
/ 31 мая 2010

Бросьте некое абстрактное исключение (например, std::exception или полученное из std::exception) или используйте технику состояния зомби, как описано здесь .

Обратите внимание, что второй метод не распространен, но имеет некоторые плюсы (и минусы).

...