Search code examples
c++oopfunction-prototypes

What should be my virtual function's prototype?


Let's say I have an abstract base class Base with a virtual function doSomething()

There are two derived classes, one of which takes no parameters in doSomething() while the other takes a structure and an integer as a parameter.

A function in another class (SomeClass) calls doSomething() using a Base* variable. It also needs to pass the parameters i mentioned for DerivedTwo.

How do i choose the prototype without using an if-else to check for the object's class at run-time?

Thank you.

    class Base {
      public:
      void virtual doSomething(); 
    }

    class DerivedOne : Base {
      public:
      void doSomething(int a,struct b);
    }

    class DerivedTwo : Base {
      public:
      void doSomething();
    }

Solution

  • One way to do this would be:

    class Base {
    public:
        Base();
        virtual ~Base();
        virtual void doSomething();
    };
    
    class DerivedOne : public Base {
    public:
        DerivedOne();
        void doSomethingElse(int a,struct b);
    };
    
    class DerivedTwo : public Base {
    public:
        DerivedTwo();
        virtual void doSomething();
    };
    

    You could then use dynamic_cast to determine the type at runtime since you seem to have a type-conditional expression someplace in SomeClass. The methods are not equal and fundamentally distinct. Also, DerivedOne::doSomething would hide Base::doSomething.

    Update

    As the others had already stated, it's often a bad smell if your program relies on type-conditional expressions. Since your example does not have enough context to offer appropriate solutions, it's hard for us to help you in this regard. If you are interested in removing the type-conditional, one of many potential solutions to this problem would be:

    class Base {
    public:
        Base();
        virtual ~Base();
        virtual void doSomething();
    };
    
    class DerivedOne : public Base {
    public:
        DerivedOne();
        // ...
        virtual void doSomething(); // << no parameters required.
                                    // they have moved to member data:
    private:
        int a;
        b another;
    };
    
    class DerivedTwo : public Base {
    public:
        DerivedTwo();
        virtual void doSomething();
    };
    

    then you could remove the type-conditional expression from your program. If you'd like help in this regard, feel free to ask here or open a new question if you feel it is more appropriate.