Thread: How to access derieved class member from base class pointer

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    113

    How to access derieved class member from base class pointer

    Hi,

    I have a problem in accessing derived class member from base class pointer.....

    I have two classes as follow:

    Code:
    class  A
    {
    };
    
    class B : public A
    {
    public:
    
    void set(char *);
    };
    I want to access set(char*) function of class B with the help of A class pointer as follow:

    Code:
     B *b = new B;
    A *a = dynamic_cast<B *>(b); 
    
    a->set(char *);
    But this is giving error that A class don't have any member set(char *)................

    Can anybody tell where I am wrong............

    Thanks

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    That's because you can't do that. If your variable is of type A it can't see items of type B. You have to cast it and save it as an object of type B.

    Talking about Type A and Type B makes me feel like I'm talking about blood types.... lol.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I'm not sure why you would do that. Are you trying some sort of polymorphism?

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Do you mean something like this?:
    Code:
    void f()
    {
        B *b = new B;
        g(b); // implicit cast to base
    }
    void g(A *a)
    {
        B *bb = dynamic_cast<B *>(a);
        bb->set("Must be a B!");
    }
    Last edited by iMalc; 10-29-2007 at 02:17 AM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Registered User
    Join Date
    Jan 2007
    Posts
    113
    Thanks for your reply...........

    Actually I want above so because I have used this functionality in a function whose return type is A*....

    i.e ..
    Code:
    A* C :: ABC()
    {
       B *b = new B;
    A *a = dynamic_cast<B *>(b); 
    a->set(char *);
    
     return a;
    }
    Ignore what is class C........Actually this is part pf project...........so I have to return object of A only.......

    Thanks

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If A* does not have a set method, why do you want to upcast before you are done working with the derived class?

    Code:
    A* C :: ABC()
    {
       B *b = new B;
       b->set(char *);
    
        return b; //implicitly upcast, hopefully
    }
    In your code you are actually dynamically casting a B pointer into a B pointer and then implicitly into a A pointer.

    However, if the function creates a new B object and accesses methods that only B has, I don't see why the return type should be a pointer to A. I would return B* and leave it up to the user to decide whether to assign the return type to A* or B* (that is, if your function is not more complicated, creating an unknown type derived from A).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Actually, if you want "proper" polymorphic behaviour (and if you are using inheritance, that's _MOST LIKELY_ what you want), then the correct thing is to declare a virtual function set() in the class A. This can be a pure virtual (that is, you can't actually CALL the virtual function in A, but it's there as a "place-holder" for derived classes).

    Then there will be no reason to have any casts, and the behaviour is predictable, doesn't rely on "knowing which class something is", etc. etc.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by matsp View Post
    Actually, if you want "proper" polymorphic behaviour (and if you are using inheritance, that's _MOST LIKELY_ what you want), then the correct thing is to declare a virtual function set() in the class A. This can be a pure virtual (that is, you can't actually CALL the virtual function in A, but it's there as a "place-holder" for derived classes).
    One just has to remember that when doing so, the class becomes abstract and can't be created, just inherited from.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    One just has to remember that when doing so, the class becomes abstract and can't be created, just inherited from.
    Yes, using pure virtual has this as a side-effect. Hide the destructor of class A, and that problem is automatically detected by the compiler.

    Or make your own error handling in the class itself - so that calling A::set() gives a suitable error message and stops the application.

    But my point was rather that if you have a pointer to a base-class and you want to call functions that are only in the derived class, then there's [usually] something wrong in the base-class.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by matsp View Post
    But my point was rather that if you have a pointer to a base-class and you want to call functions that are only in the derived class, then there's [usually] something wrong in the base-class.
    I agree on that. The function should return a B*, and the main program should decide whether to use an A* pointer in some function, and if then calling a function in B, then it's probably likely that there's more than one class derived from A and then virtual functions is the way to go.

  11. #11
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Another thing: if the set method is supposed to be called only after creating the object, you might just give parameters to the constructor and have it set right there.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by anon View Post
    Another thing: if the set method is supposed to be called only after creating the object, you might just give parameters to the constructor and have it set right there.
    Depends. If you need to be exception safe, that may not work. But yes, that's an option in some situatons.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by matsp View Post
    Depends. If you need to be exception safe, that may not work. But yes, that's an option in some situatons.

    --
    Mats
    Constructors can be exception safe It's just trickier in some cases.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by King Mir View Post
    Constructors can be exception safe It's just trickier in some cases.
    Yes, they CAN be - but as you say, it can get tricky - and it's often easier to solve that problem with a two-stage constructor, so that if you have an exception, you KNOW what has been done and what hasn't - e.g. have you filled in the "char *" value, or is it not filled in. If you do "new B" and B's constructor sets the "char *" member variable ptr = 0, then you know that part isn't going to cause an exception, but
    Code:
     
    ptr = new char[strlen(s)+1]
    could throw an exception. Now, since ptr hasn't been set to anything sensible [assuming we didn't assign it twice], so we don't know if we should delete ptr or not.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by matsp View Post
    Yes, they CAN be - but as you say, it can get tricky - and it's often easier to solve that problem with a two-stage constructor, so that if you have an exception, you KNOW what has been done and what hasn't - e.g. have you filled in the "char *" value, or is it not filled in. If you do "new B" and B's constructor sets the "char *" member variable ptr = 0, then you know that part isn't going to cause an exception, but
    Code:
     
    ptr = new char[strlen(s)+1]
    could throw an exception. Now, since ptr hasn't been set to anything sensible [assuming we didn't assign it twice], so we don't know if we should delete ptr or not.
    Simple rule -- don't catch exceptions in your constructors. Let them propagate out. If doing this would lead to a resource leak, it means you are not acquiring resources properly.

    For instance, never use new[] directly, always use boost::scoped_array or std::vector.

    For the most part, total safety of constructors can be guaranteed by initializing members in the proper order and using appropriate exception-safe members. Once you build exception-safety in at the low level it will propagate upward in your design.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Virtual base class
    By George2 in forum C++ Programming
    Replies: 7
    Last Post: 03-14-2008, 07:45 AM
  2. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  3. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  4. Member function pointer within the class
    By skorman00 in forum C++ Programming
    Replies: 1
    Last Post: 07-05-2004, 06:03 AM
  5. Virtual Base Class & Constructor :: C++
    By kuphryn in forum C++ Programming
    Replies: 2
    Last Post: 09-13-2002, 03:14 PM