1

is there any pitfall of the following;

 if (someCondition)
   throw boost::shared_ptr<SomeException>( new SomeException( "foo!" ) );

 ...

 catch( const boost::shared_ptr<SomeException>& expRef )
 {
 }
lurscher
  • 25,930
  • 29
  • 122
  • 185
  • Aside from the fact that this is unusual? Why do you want to throw a `shared_ptr`? – James McNellis Mar 07 '11 at 17:00
  • 1
    Besides the fact that you are complicating code, using a less performing construct (dynamically allocation) for something that can be written simpler and whose performance would be better... I cannot think of any other pitfall. – David Rodríguez - dribeas Mar 07 '11 at 17:09
  • Throwing shared_ptr enables propagating the exception across an asynch boundary without slicing or having to implement clone on your exception classes. – Hans Malherbe Apr 30 '16 at 08:42

3 Answers3

6

You should avoid throwing by pointer, and prefer throwing by value and catching by (const) reference.

Using a smart pointer is a way of simplifying resource management when using pointers, but if you can avoid using pointers altogether, it will be simpler doing so. Just throw a value.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • +1, this is as good an answer as Crazy Eddie's; the reason i picked his is 1) i didn't thought about what he said before, while i was aware of the fact that you mentioned 2) you can only have one right answer per question – lurscher Mar 07 '11 at 20:39
4

Yes, there is a pitfall. You won't be able to catch based on base classes:

void f()
{
  throw std::runtime_error("look here");
}
void g()
{
  throw boost::shared_ptr<std::runtime_error>("look here");
}

int main()
{
  try
  {
    f();
  }
  catch ( std::exception const& e) {}

  try { g(); }
  catch ( boost::shared_ptr<std::exception> const& e) {} // no work
}

You could of course make it throw on base, but then you can't catch the derived.

So yeah...don't do it.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
1

The only pitfall I can see is that you are doing something the hard way, when you don't have to. :-)

Normally you use a shared_pointer to manage the lifetime of an object, when that is not obvious otherwise. Here it is clear that it is not your responsibility to manage the exceptions thrown. The compiler will have to do that for you!

When the exception is handled, the runtime will destroy the shared_pointer that will then destroy the exception object. Otherwise the runtime would have destroyed the exception object directly! What do you gain?

Bo Persson
  • 90,663
  • 31
  • 146
  • 203