auto_ptr and casting

Discussion in 'C++' started by James Juno, Dec 16, 2005.

  1. James Juno

    James Juno Guest

    Hello,

    I want to do something like this:

    class A
    {
    ...
    };

    class B : public A
    {
    ...
    };

    void someFunction(const std::auto_ptr<A>& ptr)
    {
    B* b = dynamic_cast<B*>(ptr.get());
    ...
    }

    Is what I've done here the correct/safe way to handle this using auto_ptr?

    Thanks!
    JJ
     
    James Juno, Dec 16, 2005
    #1
    1. Advertising

  2. * James Juno:
    >
    > I want to do something like this:
    >
    > class A
    > {
    > ...
    > };
    >
    > class B : public A
    > {
    > ...
    > };
    >
    > void someFunction(const std::auto_ptr<A>& ptr)
    > {
    > B* b = dynamic_cast<B*>(ptr.get());
    > ...
    > }
    >
    > Is what I've done here the correct/safe way to handle this using auto_ptr?


    No, you cannot pass std::auto_ptr by reference to const.

    For dynamic_cast class A must be polymorphic.

    It's not clear what you're trying to do.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Dec 16, 2005
    #2
    1. Advertising

  3. James Juno

    mlimber Guest

    James Juno wrote:
    > Hello,
    >
    > I want to do something like this:
    >
    > class A
    > {
    > ...
    > };
    >
    > class B : public A
    > {
    > ...
    > };
    >
    > void someFunction(const std::auto_ptr<A>& ptr)
    > {
    > B* b = dynamic_cast<B*>(ptr.get());
    > ...
    > }
    >
    > Is what I've done here the correct/safe way to handle this using auto_ptr?
    >
    > Thanks!
    > JJ


    No. First of all dynamic_cast can indicate poor design. Re-examine
    yours. Second, the function should look like this:

    void someFunction( std::auto_ptr<A>& a )
    {
    std::auto_ptr<B> b( dynamic_cast<B*>(ptr.release()) );
    ...
    }

    You'll also want to check if b.get() is null, in which case the cast
    failed.

    Cheers! --M
     
    mlimber, Dec 16, 2005
    #3
  4. James Juno

    James Juno Guest

    Alf P. Steinbach wrote:
    > * James Juno:
    >> I want to do something like this:
    >>
    >> class A
    >> {
    >> ...
    >> };
    >>
    >> class B : public A
    >> {
    >> ...
    >> };
    >>
    >> void someFunction(const std::auto_ptr<A>& ptr)
    >> {
    >> B* b = dynamic_cast<B*>(ptr.get());
    >> ...
    >> }
    >>
    >> Is what I've done here the correct/safe way to handle this using auto_ptr?

    >
    > No, you cannot pass std::auto_ptr by reference to const.
    >
    > For dynamic_cast class A must be polymorphic.
    >
    > It's not clear what you're trying to do.
    >


    I got the idea to pass as const reference from "The C++ Standard
    Library" by N. Josuttis. By the way, this compiles and seems to work
    fine in vc.net, I just didn't know if it was "safe." The auto_ptr
    variable's type is set at runtime in the caller (one of several possible
    decendants of A) so I never know what I'm getting in the call to
    someFunction(). I am just using dynamic_cast as a debug check. Sorry
    for being unclear, a better explanation of this function might be:

    void someFunction(int type, const std::auto_ptr<A&> ptr)
    {
    // <type> is an enum defined elsewhere
    switch (type)
    {
    case B:
    #ifdef _DEBUG
    B* b = dynamic_cast<B*>(ptr.get());
    assert(b);
    #else
    B* b = static_cast<B*>(ptr.get());
    #endif

    ...
    case C:
    ... etc
    }
    }
     
    James Juno, Dec 16, 2005
    #4
  5. James Juno

    Andre Kostur Guest

    (Alf P. Steinbach) wrote in
    news::

    > * James Juno:
    >>
    >> I want to do something like this:
    >>
    >> class A
    >> {
    >> ...
    >> };
    >>
    >> class B : public A
    >> {
    >> ...
    >> };
    >>
    >> void someFunction(const std::auto_ptr<A>& ptr)
    >> {
    >> B* b = dynamic_cast<B*>(ptr.get());
    >> ...
    >> }
    >>
    >> Is what I've done here the correct/safe way to handle this using
    >> auto_ptr?

    >
    > No, you cannot pass std::auto_ptr by reference to const.


    Huh? Why not? As long as no modifying operations are called on ptr....
     
    Andre Kostur, Dec 16, 2005
    #5
  6. James Juno

    Andre Kostur Guest

    "mlimber" <> wrote in
    news::

    > James Juno wrote:
    >> Hello,
    >>
    >> I want to do something like this:
    >>
    >> class A
    >> {
    >> ...
    >> };
    >>
    >> class B : public A
    >> {
    >> ...
    >> };
    >>
    >> void someFunction(const std::auto_ptr<A>& ptr)
    >> {
    >> B* b = dynamic_cast<B*>(ptr.get());
    >> ...
    >> }
    >>
    >> Is what I've done here the correct/safe way to handle this using
    >> auto_ptr?
    >>
    >> Thanks!
    >> JJ

    >
    > No. First of all dynamic_cast can indicate poor design. Re-examine
    > yours. Second, the function should look like this:
    >
    > void someFunction( std::auto_ptr<A>& a )
    > {
    > std::auto_ptr<B> b( dynamic_cast<B*>(ptr.release()) );
    > ...
    > }


    Only if the OP is attempting to transfer ownership of the pointer into
    someFunction. Perhaps the OP is only attempting to use the B object.
     
    Andre Kostur, Dec 16, 2005
    #6
  7. James Juno

    James Juno Guest

    mlimber wrote:
    > James Juno wrote:
    >> Hello,
    >>
    >> I want to do something like this:
    >>
    >> class A
    >> {
    >> ...
    >> };
    >>
    >> class B : public A
    >> {
    >> ...
    >> };
    >>
    >> void someFunction(const std::auto_ptr<A>& ptr)
    >> {
    >> B* b = dynamic_cast<B*>(ptr.get());
    >> ...
    >> }
    >>
    >> Is what I've done here the correct/safe way to handle this using auto_ptr?
    >>
    >> Thanks!
    >> JJ

    >
    > No. First of all dynamic_cast can indicate poor design. Re-examine
    > yours. Second, the function should look like this:
    >
    > void someFunction( std::auto_ptr<A>& a )
    > {
    > std::auto_ptr<B> b( dynamic_cast<B*>(ptr.release()) );
    > ...
    > }
    >
    > You'll also want to check if b.get() is null, in which case the cast
    > failed.
    >
    > Cheers! --M
    >


    Perfect, thanks! That's exactly what I was looking for. The
    dynamic_cast I'm using if just for debugging, sort of like:

    void someFunction(int type, const std::auto_ptr<A>& ptr)
    {
    // <type> is an enum defined elsewhere
    switch (type)
    {
    case B:

    #ifdef _DEBUG
    B* b = dynamic_cast<B*>(ptr.get());
    assert(b != 0);
    #else
    B* b = static_cast<B*>(ptr.get());
    #endif

    ...
    case C:
    ... etc
    }
    }
     
    James Juno, Dec 16, 2005
    #7
  8. * James Juno:
    > Alf P. Steinbach wrote:
    > > * James Juno:
    > >> I want to do something like this:
    > >>
    > >> class A
    > >> {
    > >> ...
    > >> };
    > >>
    > >> class B : public A
    > >> {
    > >> ...
    > >> };
    > >>
    > >> void someFunction(const std::auto_ptr<A>& ptr)
    > >> {
    > >> B* b = dynamic_cast<B*>(ptr.get());
    > >> ...
    > >> }
    > >>
    > >> Is what I've done here the correct/safe way to handle this using auto_ptr?

    > >
    > > No, you cannot pass std::auto_ptr by reference to const.
    > >
    > > For dynamic_cast class A must be polymorphic.
    > >
    > > It's not clear what you're trying to do.
    > >

    >
    > I got the idea to pass as const reference from "The C++ Standard
    > Library" by N. Josuttis.


    Well, correction: you cannot pass a temporary (such as a function result) as
    argument here (technical reason, not allowed by the standard), and you
    shouldn't pass a variable here (style issue, passing auto_ptr implies
    passing ownership, which doesn't occur when passing by reference).


    > By the way, this compiles and seems to work fine in vc.net,


    MSVC is mostly incorrect wrt. std::auto_ptr.

    Regarding casting, consider using base class virtual functions, which you
    need anyway for dynamic_cast.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Dec 16, 2005
    #8
  9. James Juno

    mlimber Guest

    James Juno wrote:
    > mlimber wrote:
    > > James Juno wrote:
    > >> Hello,
    > >>
    > >> I want to do something like this:
    > >>
    > >> class A
    > >> {
    > >> ...
    > >> };
    > >>
    > >> class B : public A
    > >> {
    > >> ...
    > >> };
    > >>
    > >> void someFunction(const std::auto_ptr<A>& ptr)
    > >> {
    > >> B* b = dynamic_cast<B*>(ptr.get());
    > >> ...
    > >> }
    > >>
    > >> Is what I've done here the correct/safe way to handle this using auto_ptr?
    > >>
    > >> Thanks!
    > >> JJ

    > >
    > > No. First of all dynamic_cast can indicate poor design. Re-examine
    > > yours. Second, the function should look like this:
    > >
    > > void someFunction( std::auto_ptr<A>& a )
    > > {
    > > std::auto_ptr<B> b( dynamic_cast<B*>(ptr.release()) );
    > > ...
    > > }
    > >
    > > You'll also want to check if b.get() is null, in which case the cast
    > > failed.
    > >
    > > Cheers! --M
    > >

    >
    > Perfect, thanks! That's exactly what I was looking for. The
    > dynamic_cast I'm using if just for debugging, sort of like:
    >
    > void someFunction(int type, const std::auto_ptr<A>& ptr)
    > {
    > // <type> is an enum defined elsewhere
    > switch (type)
    > {
    > case B:
    >
    > #ifdef _DEBUG
    > B* b = dynamic_cast<B*>(ptr.get());
    > assert(b != 0);
    > #else
    > B* b = static_cast<B*>(ptr.get());
    > #endif
    >
    > ...
    > case C:
    > ... etc
    > }
    > }


    On second thought, the code I supplied would leak memory if the cast
    failed. Try this:

    void someFunction( std::auto_ptr<A>& a )
    {
    A* const rawA = a.release();
    std::auto_ptr<B> b( dynamic_cast<B*>(rawA) );
    if( b.get() )
    {
    ...
    }
    else
    {
    delete rawA;
    }
    }

    Cheers! --M
     
    mlimber, Dec 16, 2005
    #9
  10. * Andre Kostur:
    > (Alf P. Steinbach) wrote in
    > news::
    >
    > > * James Juno:
    > >>
    > >> I want to do something like this:
    > >>
    > >> class A
    > >> {
    > >> ...
    > >> };
    > >>
    > >> class B : public A
    > >> {
    > >> ...
    > >> };
    > >>
    > >> void someFunction(const std::auto_ptr<A>& ptr)
    > >> {
    > >> B* b = dynamic_cast<B*>(ptr.get());
    > >> ...
    > >> }
    > >>
    > >> Is what I've done here the correct/safe way to handle this using
    > >> auto_ptr?

    > >
    > > No, you cannot pass std::auto_ptr by reference to const.

    >
    > Huh? Why not? As long as no modifying operations are called on ptr....


    You cannot pass a temporary as actual argument because std::auto_ptr does
    not have a copy constructor taking std::auto_ptr by reference to const.

    You can but shouldn't pass a variable as actual argument.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Dec 16, 2005
    #10
  11. James Juno

    James Juno Guest

    Andre Kostur wrote:
    > "mlimber" <> wrote in
    > news::
    >
    >> James Juno wrote:
    >>> Hello,
    >>>
    >>> I want to do something like this:
    >>>
    >>> class A
    >>> {
    >>> ...
    >>> };
    >>>
    >>> class B : public A
    >>> {
    >>> ...
    >>> };
    >>>
    >>> void someFunction(const std::auto_ptr<A>& ptr)
    >>> {
    >>> B* b = dynamic_cast<B*>(ptr.get());
    >>> ...
    >>> }
    >>>
    >>> Is what I've done here the correct/safe way to handle this using
    >>> auto_ptr?
    >>>
    >>> Thanks!
    >>> JJ

    >> No. First of all dynamic_cast can indicate poor design. Re-examine
    >> yours. Second, the function should look like this:
    >>
    >> void someFunction( std::auto_ptr<A>& a )
    >> {
    >> std::auto_ptr<B> b( dynamic_cast<B*>(ptr.release()) );
    >> ...
    >> }

    >
    > Only if the OP is attempting to transfer ownership of the pointer into
    > someFunction. Perhaps the OP is only attempting to use the B object.
    >


    Yes, the OP is only trying to use the object. If style semantics dictate
    that an auto_ptr as a function parameter should imply ownership
    transfer, then what's better in this case? It's becoming more of a
    headache to use auto_ptr than to just deal with resource management
    manually.
     
    James Juno, Dec 16, 2005
    #11
  12. James Juno

    mlimber Guest

    James Juno wrote:
    > Andre Kostur wrote:
    > > "mlimber" <> wrote in
    > > news::
    > >
    > >> James Juno wrote:
    > >>> Hello,
    > >>>
    > >>> I want to do something like this:
    > >>>
    > >>> class A
    > >>> {
    > >>> ...
    > >>> };
    > >>>
    > >>> class B : public A
    > >>> {
    > >>> ...
    > >>> };
    > >>>
    > >>> void someFunction(const std::auto_ptr<A>& ptr)
    > >>> {
    > >>> B* b = dynamic_cast<B*>(ptr.get());
    > >>> ...
    > >>> }
    > >>>
    > >>> Is what I've done here the correct/safe way to handle this using
    > >>> auto_ptr?
    > >>>
    > >>> Thanks!
    > >>> JJ
    > >> No. First of all dynamic_cast can indicate poor design. Re-examine
    > >> yours. Second, the function should look like this:
    > >>
    > >> void someFunction( std::auto_ptr<A>& a )
    > >> {
    > >> std::auto_ptr<B> b( dynamic_cast<B*>(ptr.release()) );
    > >> ...
    > >> }

    > >
    > > Only if the OP is attempting to transfer ownership of the pointer into
    > > someFunction. Perhaps the OP is only attempting to use the B object.
    > >

    >
    > Yes, the OP is only trying to use the object. If style semantics dictate
    > that an auto_ptr as a function parameter should imply ownership
    > transfer, then what's better in this case? It's becoming more of a
    > headache to use auto_ptr than to just deal with resource management
    > manually.


    If you don't intend to transfer ownership to the function, then your
    original code looks fine.

    Cheers! --M
     
    mlimber, Dec 16, 2005
    #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. kevin
    Replies:
    11
    Views:
    5,843
    Andrew McDonagh
    Jan 8, 2005
  2. Siemel Naran

    auto_ptr<Derived> to auto_ptr<Base>

    Siemel Naran, Jan 10, 2005, in forum: C++
    Replies:
    2
    Views:
    1,586
    Dave Rahardja
    Jan 11, 2005
  3. Wally Barnes
    Replies:
    3
    Views:
    545
    Wally Barnes
    Nov 20, 2008
  4. Sosuke

    Up casting and down casting

    Sosuke, Dec 20, 2009, in forum: C++
    Replies:
    2
    Views:
    596
    James Kanze
    Dec 20, 2009
  5. Sousuke
    Replies:
    9
    Views:
    1,189
    Bart van Ingen Schenau
    Mar 16, 2010
Loading...

Share This Page