throwing exception from constructor .

Discussion in 'C++' started by mangesh, Apr 6, 2006.

  1. mangesh

    mangesh Guest

    I read , FAQ : 17.4] How should I handle resources if my constructors
    may throw exceptions?

    Above faq says that use smart pointer in construcors . Because if
    exception is thrown from constructor it's destructor is not run .So to
    avoid memory lekage use smart pointer .
    But if exception is thrown we can release resources in catch block . So
    use of smart pointer is not must , we have this secnd option . Am i
    right ?
     
    mangesh, Apr 6, 2006
    #1
    1. Advertising

  2. mangesh wrote:
    > I read , FAQ : 17.4] How should I handle resources if my constructors
    > may throw exceptions?
    >
    > Above faq says that use smart pointer in construcors . Because if
    > exception is thrown from constructor it's destructor is not run .So to
    > avoid memory lekage use smart pointer .
    > But if exception is thrown we can release resources in catch block .
    > So use of smart pointer is not must , we have this secnd option . Am i
    > right ?


    You can release in a catch block, unless you lose track of the resource
    to be released. If it's a local object in the body of the construct,
    how do you know its value to release in the catch block?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 6, 2006
    #2
    1. Advertising

  3. mangesh

    Ben Pope Guest

    mangesh wrote:
    > I read , FAQ : 17.4] How should I handle resources if my constructors
    > may throw exceptions?
    >
    > Above faq says that use smart pointer in construcors . Because if
    > exception is thrown from constructor it's destructor is not run .So to
    > avoid memory lekage use smart pointer .
    > But if exception is thrown we can release resources in catch block . So
    > use of smart pointer is not must , we have this secnd option . Am i
    > right ?


    Consider:
    class ResourceHolder {
    int* pointer1;
    int* pointer2;
    // prevent copy and assignment
    ResourceHolder(const ResourceHolder&);
    ResourceHolder& operator=(const ResourceHolder&);
    public:
    ResourceHolder() : pointer1(new int(1)), pointer2(new int(2)) {}
    ~ResourceHolder() {
    delete pointer1;
    delete pointer2;
    }
    }

    The line:
    ResourceHolder r;

    Requires allocation of 2 ints, either of which could fail and throw an
    exception. The problem is: which one failed?

    If you change the constructor to include try catch:
    ResourceHolder() : pointr1(0), pointer2(0) {
    // if this throws, it's ok
    pointer1 = new int(1);
    try {
    // if this throws, clean up pointer 1
    pointer2 = new int(2);
    } catch () {
    delete pointer1;
    }
    }

    That's starting to get a bit messy, imagine scaling that to 5 resources,
    it's better to apply RAII to all resources, and just use a smart
    pointer, even if it's just std::auto_ptr<int>.

    It's much less error prone.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
     
    Ben Pope, Apr 6, 2006
    #3
  4. mangesh

    mangesh Guest

    can't we call destructor explicitly in catch block ?
     
    mangesh, Apr 6, 2006
    #4
  5. mangesh wrote:
    > can't we call destructor explicitly in catch block ?


    Yes you can.

    The following should work just fine but in general it might be not
    trivial to ensure that the destructor can be safely called for a
    partially constructed object. E.g. in this case the initialization of
    the pointers to 0 is crucial.

    ResourceHolder() : pointer1(0), pointer2(0) {
    try {
    pointer1 = new int(1);
    pointer2 = new int(2);
    } catch(...) {
    this->ResourceHolder::~ResourceHolder();
    throw;
    }
    }
     
    Markus Schoder, Apr 6, 2006
    #5
  6. mangesh

    Ben Pope Guest

    mangesh wrote:
    > can't we call destructor explicitly in catch block ?


    It's not advisable to delete something that was not allocated. If
    pointer1 fails allocation, and you call the destructor, you will delete
    two objects that were not allocated. Of course, if the pointers were
    initialised to 0, then calling delete on them is ok.

    What do you have against auto_ptr? It does the job you require, with
    neat and safe syntax. Use it.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
     
    Ben Pope, Apr 6, 2006
    #6
  7. Ben Pope wrote:
    > mangesh wrote:
    > > can't we call destructor explicitly in catch block ?

    >
    > What do you have against auto_ptr? It does the job you require, with
    > neat and safe syntax. Use it.


    auto_ptr as member is generally not advisable because of its odd copy
    semantics. You can of course use it locally and then assign to the
    actual member later:

    auto_ptr<int> p1 = new int(1);
    auto_ptr<int> p2 = new int(2);

    // ... other stuff that might throw ...

    pointer1 = p1.release();
    pointer2 = p2.release();
     
    Markus Schoder, Apr 6, 2006
    #7
  8. mangesh

    Ben Pope Guest

    Markus Schoder wrote:
    > Ben Pope wrote:
    >> mangesh wrote:
    >>> can't we call destructor explicitly in catch block ?

    >> What do you have against auto_ptr? It does the job you require, with
    >> neat and safe syntax. Use it.

    >
    > auto_ptr as member is generally not advisable because of its odd copy
    > semantics.


    Not much more odd than a pointer, it won't get you into any more
    trouble, besides, in my example I had disabled copying. This is fairly
    common in classes that manage resources.

    The point is that there are tools to help, the OP should use them.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
     
    Ben Pope, Apr 6, 2006
    #8
  9. Ben Pope wrote:
    > Markus Schoder wrote:
    > > Ben Pope wrote:
    > >> mangesh wrote:
    > >>> can't we call destructor explicitly in catch block ?
    > >> What do you have against auto_ptr? It does the job you require, with
    > >> neat and safe syntax. Use it.

    > >
    > > auto_ptr as member is generally not advisable because of its odd copy
    > > semantics.

    >
    > Not much more odd than a pointer, it won't get you into any more
    > trouble, besides, in my example I had disabled copying. This is fairly
    > common in classes that manage resources.


    auto_ptr has a copy constructor that modifies the _source_. This is as
    odd as it gets in my book.
     
    Markus Schoder, Apr 6, 2006
    #9
  10. mangesh

    Cy Edmunds Guest

    "Markus Schoder" <> wrote in message
    news:...
    > Ben Pope wrote:
    >> Markus Schoder wrote:
    >> > Ben Pope wrote:
    >> >> mangesh wrote:
    >> >>> can't we call destructor explicitly in catch block ?
    >> >> What do you have against auto_ptr? It does the job you require, with
    >> >> neat and safe syntax. Use it.
    >> >
    >> > auto_ptr as member is generally not advisable because of its odd copy
    >> > semantics.

    >>
    >> Not much more odd than a pointer, it won't get you into any more
    >> trouble, besides, in my example I had disabled copying. This is fairly
    >> common in classes that manage resources.

    >
    > auto_ptr has a copy constructor that modifies the _source_. This is as
    > odd as it gets in my book.
    >


    I agree. IMHO auto_ptr should never be used as a member in a class. No
    matter how carefully you document the resulting behavior, when somebody
    writes

    y = x;

    and it changes x, confusion if not disaster is likely to follow.

    boost::shared_ptr doesn't have this problem.

    Cy
     
    Cy Edmunds, Apr 7, 2006
    #10
  11. Cy Edmunds wrote:
    > "Markus Schoder" <> wrote in message
    > news:...
    > > Ben Pope wrote:
    > >> Markus Schoder wrote:
    > >> > Ben Pope wrote:
    > >> >> mangesh wrote:
    > >> >>> can't we call destructor explicitly in catch block ?
    > >> >> What do you have against auto_ptr? It does the job you require, with
    > >> >> neat and safe syntax. Use it.
    > >> >
    > >> > auto_ptr as member is generally not advisable because of its odd copy
    > >> > semantics.
    > >>
    > >> Not much more odd than a pointer, it won't get you into any more
    > >> trouble, besides, in my example I had disabled copying. This is fairly
    > >> common in classes that manage resources.

    > >
    > > auto_ptr has a copy constructor that modifies the _source_. This is as
    > > odd as it gets in my book.
    > >

    >
    > I agree. IMHO auto_ptr should never be used as a member in a class. No
    > matter how carefully you document the resulting behavior, when somebody
    > writes
    >
    > y = x;
    >
    > and it changes x, confusion if not disaster is likely to follow.
    >
    > boost::shared_ptr doesn't have this problem.
    >
    > Cy


    shared_ptr is slower :)

    and unnecessary using move semantics

    any class with move semantics can use auto_ptr without problems :)
     
    Diego Martins, Apr 10, 2006
    #11
  12. mangesh

    Guest

    Cy Edmunds wrote:
    > IMHO auto_ptr should never be used as a member in a class. No
    > matter how carefully you document the resulting behavior, when somebody
    > writes
    >
    > y = x;
    >
    > and it changes x, confusion if not disaster is likely to follow.


    Nonsense. BY that argument, raw pointers shouldn't be used in classes,
    because after y = x, changing x shouldn't change y.
    Of course, that doesn't happen with real classes using raw pointer,
    because
    they copy the pointed-to object and not the pointer. The same applies
    to
    auto_ptr members. Your copy ctor will simply copy the pointed-to
    object,
    and not change the source auto_ptr. You usually can't, because inside
    your copy ctor the source auto_ptr is const (assuming X::X(X const&
    src)

    HTH,
    Michiel Salters
     
    , Apr 11, 2006
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. KJ
    Replies:
    5
    Views:
    384
    John Saunders
    Jul 25, 2003
  2. mihai
    Replies:
    21
    Views:
    1,142
    John Carson
    Jun 3, 2005
  3. Generic Usenet Account
    Replies:
    10
    Views:
    2,245
  4. Richard Maher
    Replies:
    38
    Views:
    1,096
    Larry K. Wollensham
    Apr 15, 2009
  5. Vladimir Jovic
    Replies:
    19
    Views:
    1,058
    Victor Bazarov
    Sep 30, 2009
Loading...

Share This Page