Search code examples
c++inheritancestaticpure-virtual

Calling a derived-class implementation of a pure virtual function statically using a function in the base class


There's some discussion of this topic elsewhere in stackoverflow, but I haven't really found a clear answer to my question.

My setup is like this:

class BaseClass
{
    virtual short return_number_for_thing1(std::string thing1)=0; //note the pure virtual
    virtual short return_number_for_thing2(std::string thing2)=0;
    virtual short return_number_for_thing(std::string thing); //virtual is probably not necessary here, I can get rid of it if need be
}

short BaseClass::return_number_for_thing(std::string thing)
{ //pretend thing1 and thing2 are enum'ed somewhere
    if      (thing == thing1) return return_number_for_thing1(thing);
    else if (thing == thing2) return return_number_for_thing2(thing);
}

class DerivedClass1 : BaseClass
{
    short return_number_for_thing1(std::string thing1);
    short return_number_for_thing2(std::string thing2);
}

class DerivedClass2 : BaseClass
{
    short return_number_for_thing1(std::string thing1);
    short return_number_for_thing2(std::string thing2);
}

My question is, why can't I write code like this:

short number_i_want = DerivedClass2::return_number_for_thing(thing);

I sort of understand that trying to call return_number_for_thing from a BaseClass pointer doesn't make sense, since it doesn't know whether to call the routines for DerivedClass1 or DerivedClass2, but if I give it the scope of DerivedClass2, shouldn't it be able to figure out what I want? For now, I create a blank instance of DerivedClass2 or DerivedClass1 when I need to, but it seems to me that I shouldn't have to do that.


Solution

  • In C++, virtual and static don't mix.

    • virtual = concrete operation depends on the type of an object.
    • static = you don't need an object.

    It is certainly possible to imagine such a thing, however. If C++ had something like meta types, allowing you to treat regular types as objects, then it would not be such a strange idea anymore.

    Pseudo-code (using an imaginary syntax):

    void f(Class base_class)
    {
       base_class.StaticMethod();
    }
    
    struct Base
    {
      virtual static StaticMethod(); // impossible in C++
    };
    
    struct Derived : Base
    {
      virtual static StaticMethod(); // impossible in C++
    };
    
    f(Base); // impossible in C++
    f(Derived); // impossible in C++
    

    The desire to create something like static virtual functions is sometimes a symptom for the real need (which C++ cannot fulfill out of the box): treating types as objects.