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.