-1
  // In Common.hpp
    #include <iostream>
    using namespace std;
    
    class Common
    {
    public:
        Common( ) { };
        virtual ~Common( ) { };
        virtual void func()     
        {
            std::cout << "This is Common\n";
            genericPtr->XYZ(); /// If A is instantiated than genericPtr should become A class ptr or else B class ptr
        };
    };
    
    // In B.hpp
    #include "Common.hpp"
    
    class B : public Common
    {
    public:
        B( ) { };
        virtual ~B( ) { };
        void XYZ( ) { printf("I am B\n"); };
    };
    
    // In A.hpp
    #include "Common.hpp"
    
    class A : public Common
    {
    public:
        A( ) { };
        virtual ~A( ) { };
        void XYZ( ) { printf("I am A\n"); };
    };
    
    // Random.cpp
    #include "A.hpp"
    
    int main()
    {
        A *a = new A();
    }

For example, I am instantiating A in Random.cpp file. Now by calling 'func()' from Random.cpp file, I want to print 'I am A', how to do that? Also I am not sure if the instantiation is correct. I could be Common *a = new A();, I am not sure about it.

The most important part is I want to know about the genericPtr in 'func', how does genericPtr know which class has been instantiated? What code should I write so that genericPtr knows that class A has been instantiated and it has to call XYZ() method of class A and not class B?

EDIT: Some kind of RTTI method if it could be used?

  • 1
    I think you may want to read about [virtual dispatching](https://stackoverflow.com/q/3972548/260313). – rturrado Jan 03 '22 at 19:44
  • This is typically handled by using a virtual table. The parent object has a table of function names and their addresses. When the derived class is instantiated, it can replace the parent class function addresses in the table with addresses to the ones from the derived class. – NathanOliver Jan 03 '22 at 19:44
  • @NathanOliver Do you have any handy example which I can refer? I am not sure how to create this virtual table. – user17825268 Jan 03 '22 at 19:47
  • 1
    We don't create it, it is created by the compiler once you use the `virtual` keyword. – NathanOliver Jan 03 '22 at 19:49
  • No need for `genericPtr` at all. Its role, given the context provided by the code, would be handled by `this`. **But...** `XYZ` must be a `virtual` function declared by `Common`. – user4581301 Jan 03 '22 at 19:54
  • 2
    This is a C++ fundamental. I think it would be more effective if you read or re-read the section in your C++ programming text on polymorphism and `virtual` functions and it will cover the topic better than we can do here. If you don't have a good text, [here's a list of good candidates](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – user4581301 Jan 03 '22 at 20:08

1 Answers1

2

I think you are misunderstanding how inheritance works. The Parent class should not have any understanding of the child class, and definitely does not need to have some sort of pointer to call inherited functions from a child class object.

See the below change to your code, I believe this is what you are trying to accomplish:

    #include <iostream>
    
    using namespace std;
    
    class Common
    {
    public:
        Common( ) { };
        virtual ~Common( ) { };
        virtual void XYZ(){
          std::cout << "I am Common\n";
        };
        void func()     
        {
            std::cout << "Base: Calling XYZ\n";
            XYZ(); // no need to use any weird pointer here, just call the virtual function
        };
    };
    
    class B : public Common
    {
    public:
        B( ) { };
        virtual ~B( ) { };
        void XYZ( ) { std::cout << "I am B\n"; };
    };
    
    class A : public Common
    {
    public:
        A( ) { };
        virtual ~A( ) { };
        void XYZ( ) { std::cout << "I am A\n"; };
    };
    
    int main()
    {
        A      *a = new A();
        B      *b = new B();
        Common *c = new Common();
        a->func();
        b->func();
        c->func();
    }

This program prints the following output:

Base: Calling XYZ
I am A
Base: Calling XYZ
I am B
Base: Calling XYZ
I am Common
Sam
  • 109
  • 5
  • Yes, but I got an issue here: XYZ() is different for both class A and B. For class A, it is XYZ( int a) and for class B it is just XYZ() Any idea on how to solve that? – user17825268 Jan 03 '22 at 21:06
  • Not that I know of. You'd have to add an extra declaration to the `Common` class for `virtual void XYZ( int a)` and then override it in the A class. – Sam Jan 03 '22 at 21:18