Alternative to c++ static virtual methods

前端 未结 12 2178
深忆病人
深忆病人 2020-12-04 21:58

In C++ is not possible to declare a static virtual function, neither cast a non-static function to a C style function pointer.

Now, I have a plain ol\' C SDK that us

12条回答
  •  鱼传尺愫
    2020-12-04 22:19

    These things would certainly be useful- namely, to force all objects in a class hierarchy to expose a factory method instead of an ordinary constructor. Factories are very useful for ensuring you never build invalid objects, a design guarantee that you cannot enforce nearly as well with ordinary constructors.

    To build 'virtual statics' requires building your own "static v-table" by hand into all the objects that need it. Ordinary virtual member functions work because the compiler builds a secret table of function pointers called the VTABLE into all instances of your class. When you build a "T" object, the function pointers in this table are assigned to the addresses of 1st ancestor providing that API. Overriding a function then simply becomes replacing the original pointer in the object you get from 'new' with the new one provided in the derived class. Of course, the compiler and runtime handle this all for us.

    But, back in the really old days before modern c++ (so I'm told), you had to set this magic up yourself. And that's still the case for virtual statics. The good news is this- the vtable you build by hand for them is actually simpler than the 'ordinary' one, its entries are no more expensive in any way-including space & performance- than those for member functions. Just define the base class with an EXPLICIT set of function pointers (the static vtable) for the APIs you want supported:

    template
    class VirtualStaticVtable {
    private:
       typedef T (*StaticFactory)(KnownInputParameters params);
    
       StaticFactory factoryAPI;  // The 1 and only entry in my static v-table
    
    protected:
       VirtualStaticVtable(StaticFactory factoryApi) : factoryAPI(factoryApi) {}
       virtual ~VirtualStaticVtable() {}
    };
    

    Now, every object that should support a static factory method can be derived from this class. They quietly pass in their own factory to their constructor, and it only adds 1 pointer to the resulting objects' sizes (just like an ordinary VTable entry).

    Strousup and co. could still add this idiomatic pattern to the core language if they wanted to. It wouldn't even be that hard. Every object in such a "C+++" would simply have 2 vtables instead of 1- 1 for member functions taking 'this' as an argument and 1 for ordinary function pointers. Until that day, however, we're stuck with manual vtables just like the old C-programmers were in the days before c++.

提交回复
热议问题