简体   繁体   中英

What to throw in a C++ class wrapping a C library?

I have to create a set of wrapping C++ classes around an existing C library.

For many objects of the C library, the construction is done by calling something like britney_spears* create_britney_spears() and the opposite function void free_britney_spears(britney_spears* brit) .

If the allocation of a britney_spears fails, create_britney_spears() returns NULL .

This is, as far as I know, a very common pattern.

Now I want to wrap this inside a C++ class.

//britney_spears.hpp

class BritneySpears
{
  public:

    BritneySpears();

  private:

    boost::shared_ptr<britney_spears> m_britney_spears;
};

And here is the implementation:

// 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 ??!
  }
}

So the question is in the code sample: What should I throw to abort the constructor ?

I know I can throw almost anything, but I want to know what is usually done. I have no other information about why the allocation failed. Should I create my own exception class ? Is there a std exception for such cases ?

Many thanks.

You would not want to derive a BritneyFailedToConstruct exception. My experience is that you should keep exception hierarchies as flat as possible (I use one single type per library). The exception should derive from std::exception, and should somehow contain a message that is accessible via std:;exceptions virtual what() function. You then throw it in your constructor:

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

The following is the declaration for the exception class I use in my own utility library:

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__  ); \
}   \

The macro is for conveniently adding the file name and line number, and providing stream formatting for the message. This lets you say things like:

ATHROW( "britney construction failed - bad booty value of " << booty );

Throw some abstract exception (like std::exception or derived from std::exception ) or use the zombie-state technique as described here .

Note that the second method isn't common but has some pros (as well as cons).

我会抛出一个runtime_error链接 )或从runtime_error派生的自己类的对象。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM