Search code examples
c++classcastingdescendant

pointers to object and descendants in C++


I am working on a simple C++ (under Linux) project, which will have pointers to objects. I have class A, class B which extends A, and class C which extends B. Class C has a method (test) that does not exist in A or B.

Is is possible to have a single pointer 'p' that can point to an object of type A, B, and C ? How would I define that pointer?

Secondly, since a.test() doesn't exist, but c.test() does, can my generic pointer 'p' call p->test() ? Will this compile? What if at run time p points to an object of class A and I call p->test()? Is that a runtime error?


Solution

  • Is is possible to have a single pointer that can point to an object of type A, B, and C ?

    I assume you mean "that can either point to an A object or to B object or to a C object", right?

    Yes, you can have such a pointer.

    How would I define that pointer?

    A*

    A base-class pointer can point to objects of derived classes.

    Secondly, how would I call methods of the object if the pointer can point to A/B/C classes?

    You define a virtual function in A and override it in B and C. Then, when you call the method through your A*, the language will perform dynamic dispatch, i.e. it will automatically call the right method depending on whether your A* points to an A, to a B or to a C.

    Do I need to cast them before calling the methods?

    No. That would pretty much defeat the purpose of virtual functions.

    Here is a complete example:

    #include <iostream>
    
    class A
    {
    public:
        virtual ~A() {} // not really needed in this program,
                        // but almost always needed in real code
                        // when a class has a virtual function
        virtual void method() { std::cout << "A::method\n"; }
    };
    
    class B : public A
    {
    public:
        virtual void method() override { std::cout << "B::method\n"; }
    };
    
    class C : public A
    {
    public:
        virtual void method() override { std::cout << "C::method\n"; }
    };
    
    int main()
    {
        A a;
        B b;
        C c;
        A* ptr = &a;
        ptr->method();
        ptr = &b;
        ptr->method();
        ptr = &c;
        ptr->method();
    }
    

    Output:

    A::method
    B::method
    C::method