Using Ptr of derived class to point to base class and viceversa

Discussion in 'C++' started by Bhan, Sep 19, 2005.

  1. Bhan

    Bhan Guest

    Using Ptr of derived class to point to base class and viceversa
    class base
    {
    ....
    }
    class derived : public base
    {
    ....
    }

    I want to know any practical scenario when this is used
    a. B b;
    D *p = &b;

    b. B *b;
    D d;
    b = &d;



    Can any one explain it?I know it is theoritically OK.But i am not able
    why to do such things?

    Thanks in Advance,
    Bhanu
    Bhan, Sep 19, 2005
    #1
    1. Advertising

  2. Bhan

    placid Guest

    Bhan wrote:
    > Using Ptr of derived class to point to base class and viceversa
    > class base
    > {
    > ...
    > }
    > class derived : public base
    > {
    > ...
    > }
    >
    > I want to know any practical scenario when this is used
    > a. B b;
    > D *p = &b;
    >
    > b. B *b;
    > D d;
    > b = &d;
    >
    >
    >
    > Can any one explain it?I know it is theoritically OK.But i am not able
    > why to do such things?


    doesnt this lead to the Slicing Problem ?

    >
    > Thanks in Advance,
    > Bhanu
    placid, Sep 19, 2005
    #2
    1. Advertising

  3. placid wrote:
    > Bhan wrote:
    >
    >>Using Ptr of derived class to point to base class and viceversa
    >>class base
    >>{
    >>...
    >>}
    >>class derived : public base
    >>{
    >>...
    >>}
    >>
    >>I want to know any practical scenario when this is used
    >>a. B b;
    >> D *p = &b;


    No practical use of downcasting from an object not of the derived type.

    >>
    >>b. B *b;
    >> D d;
    >> b = &d;


    Upcasting: Happens all the time.

    >>
    >>Can any one explain it?I know it is theoritically OK.But i am not able
    >>why to do such things?

    >
    >
    > doesnt this lead to the Slicing Problem ?


    Slicing happens when you copy the object. The OP is simply taking
    pointers to the object.
    Gianni Mariani, Sep 19, 2005
    #3
  4. Bhan

    Bhan Guest

    So you mean this is normally used?
    >Upcasting: Happens all the time.


    B b;
    D *p = &b;
    But why do this ?why not have a ptr to base class itself ?(below)

    B b;
    B *p = &b;

    Can you give the use of these two?
    B b;
    B *p = &b;
    D *p = &b;
    Bhan, Sep 19, 2005
    #4
  5. Bhan

    John Carson Guest

    "Bhan" <> wrote in message
    news:
    > Using Ptr of derived class to point to base class and viceversa
    > class base
    > {
    > ...
    > }
    > class derived : public base
    > {
    > ...
    > }
    >
    > I want to know any practical scenario when this is used
    > a. B b;
    > D *p = &b;


    You shouldn't do this because the derived class will usually have members
    that the base class does not. The derived class pointer will allow you to
    try to access members of the derived class than don't exist in the base
    class object, with possibly disastrous consequences.

    > b. B *b;
    > D d;
    > b = &d;


    This is safe and very useful, though it rarely occurs in the context that
    you have shown. It occurs in two main contexts.

    1. Containers of pointers. The container (an array or vector or whatever)
    can usually only store pointers of a single type. If you want it to point to
    both base and derived class objects, then you store base pointers and assign
    to those base pointers the addresses of both base and derived class objects.
    You can then iterate over all the members in the container, calling the same
    function for each. If the function is virtual, then you can get a different
    function for the pointers pointing to the derived class objects as compared
    to the pointers pointing to the base class objects (this is known as
    run-time polymorphism). For non-virtual functions, you get the same function
    in both cases, but this is OK since the function is a member of both the
    base and the derived class (with public inheritance, any public function in
    the base class becomes a public function in the derived class).

    2. Functions that take pointer arguments. Given, say:

    Base b;
    Derived d;

    void foo(Base *ptr)
    {
    ptr->MemberFunction();
    }

    you can call this function using the address of either a base class or a
    derived class object:

    foo(&b);
    foo(&d);

    The effect of the first is:

    ptr = &b;
    ptr->MemberFunction();

    The effect of the second is:

    ptr = &d;
    ptr->MemberFunction();


    --
    John Carson
    John Carson, Sep 19, 2005
    #5
  6. Bhan

    Bhan Guest

    b. B *b;
    > D d;
    > b = &d;

    Can I summarize my understanding like this?

    Whenever you have the provision to store only base ptr,store the base
    ptr that points to dervied object.

    When u retrieve it,use static_cast and get the req derived object.Right?
    Bhan, Sep 19, 2005
    #6
  7. Bhan wrote:
    > b. B *b;
    >
    >> D d;
    >> b = &d;

    >
    > Can I summarize my understanding like this?
    >
    > Whenever you have the provision to store only base ptr,store the base
    > ptr that points to dervied object.
    >
    > When u retrieve it,use static_cast and get the req derived object.Right?
    >


    static_cast if you are sure that the pointer points to the derived
    class. Use dynamic_cast if you are not sure and you have a polymorphic
    base class.

    john
    John Harrison, Sep 19, 2005
    #7
  8. Bhan

    John Carson Guest

    "Bhan" <> wrote in message
    news:
    > b. B *b;
    >> D d;
    >> b = &d;

    > Can I summarize my understanding like this?
    >
    > Whenever you have the provision to store only base ptr,store the base
    > ptr that points to dervied object.


    Yes.

    > When u retrieve it,use static_cast and get the req derived
    > object.Right?


    Most of the time you don't need any cast. You call functions that are
    declared in the base class and may or may not be virtual.

    If you want to call a derived class function that does not exist in the base
    class --- or does exist but is not virtual --- then a cast is necessary. See
    John Harrison's remarks on this.

    Note that these issues only arise in situations where you don't
    automatically know the type of object pointed to, as with a container of
    pointers that can point to both base and derived class objects. In such
    contexts, it is simplest if you can make the same function call regardless
    of what the pointer points to and you achieve different behaviour by using
    virtual functions. Having to figure out what is pointed to --- and making
    different function calls on that basis --- is inelegant and error prone.

    If you have derived objects and only derived objects and you know it, then
    you just use pointers to derived objects (if you use pointers at all) and
    none of these complications arise.

    --
    John Carson
    John Carson, Sep 19, 2005
    #8
  9. Bhan

    Greg Guest

    Bhan wrote:
    > b. B *b;
    > > D d;
    > > b = &d;

    > Can I summarize my understanding like this?
    >
    > Whenever you have the provision to store only base ptr,store the base
    > ptr that points to dervied object.
    >
    > When u retrieve it,use static_cast and get the req derived object.Right?


    One thing to remember of course is that a pointer to a derived class is
    also a pointer to the base class. It can be used anywhere a base class
    pointer can be used. An instance of the derived class is an instance of
    the base class.

    And while "downcasts" from a base class to a derived class are
    sometimes necessary, using them is not considered a good programming
    practice. A lot of downcasts in source code generally indicate a
    weakness in the program's class hierarchy or implementation. After all,
    if the client has a base pointer it should not need to "know" about its
    derived classes. That is the whole point of having an abstraction in
    the first place. On the other hand if a client does need an object of
    the derived class for some reason, then the question becomes how did it
    wind up with a pointer to the base class.

    Greg
    Greg, Sep 19, 2005
    #9
  10. Bhan

    Bhan Guest

    Thats fine.
    I am satisfied with this.
    So,Can I summarize my understanding like this?


    Whenever you have the provision to store only base ptr,store the base
    ptr that points to dervied object.


    When u retrieve it,use dynamic_cast or static_cast(depending on the
    situation)and get the req derived object.Right?

    Thanks
    Bhanu
    Bhan, Sep 19, 2005
    #10
  11. Bhan

    mlimber Guest

    Bhan wrote:
    > b. B *b;
    > > D d;
    > > b = &d;

    > Can I summarize my understanding like this?
    >
    > Whenever you have the provision to store only base ptr,store the base
    > ptr that points to dervied object.
    >
    > When u retrieve it,use static_cast and get the req derived object.Right?


    If I understand you correctly, I don't think your statement is
    accurate. You shouldn't always refer to a derived class with a base
    class pointer just because you can do so. Certainly, one of the main
    reasons for using inheritance is to allow abstraction from the
    specifics of derived classes, but this is generally done by using
    virtual functions to create interfaces for the derived classes to
    implement.

    Casting back to the derived type from a pointer to the base class is
    generally discouraged. If you need to refer to the derived object as
    the derived type, not as the more general base type, then generally
    speaking you should not be using a pointer to the base class at that
    point in the code.

    Consider:

    // Abstract base class; cannot be instantiated
    struct Shape { virtual void Draw() const = 0; }

    // A concrete class
    struct Square : public Shape
    {
    Square( float length ) : length_( length ) { /* ... */ }

    // Implement the virtual function
    void Draw() const { /*...*/ }

    // An additional function that applies to Squares
    void Rotate( float angle ) { /*...*/ }

    private:
    const float length_;
    };

    // Another concrete class
    struct Circle : public Shape
    {
    Circle( float radius ) : radius_( radius ) { /* ... */ }
    void Draw() const { /*...*/ }
    private:
    const float radius_;
    };

    Now you can use the base classes to refer to the derived classes and no
    cast is needed:

    void Foo( const Shape& shape )
    {
    // ...
    shape.Draw();
    // ...
    }

    We could pass a Circle or a Square into this function. If we needed to
    call Square::Rotate(), we should probably not do so from Foo since
    Shape (and its subclass Circle) does not support the Rotate operation.
    The design should be altered so that the object we have is guaranteed
    to be a Square, e.g.,

    void Bar( Square& square )
    {
    // ...
    square.Rotate( 20.5 );
    Foo( square );
    // ...
    }

    You might be interested in the FAQ for this group, which as several
    sections on inheritance:

    http://www.parashift.com/c -faq-lite/

    Cheers! --M
    mlimber, Sep 19, 2005
    #11
    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. Replies:
    1
    Views:
    387
    myork
    May 23, 2007
  2. Replies:
    1
    Views:
    375
    Victor Bazarov
    May 23, 2007
  3. Rajya
    Replies:
    2
    Views:
    308
    Rajya
    Feb 18, 2010
  4. Johannes Schaub
    Replies:
    11
    Views:
    583
    James Kanze
    Aug 7, 2011
  5. Saraswati lakki
    Replies:
    0
    Views:
    1,298
    Saraswati lakki
    Jan 6, 2012
Loading...

Share This Page