Why can't static functions be virtual

Bill Baxter dnewsgroup at billbaxter.com
Wed Jan 17 00:54:16 PST 2007


John McAuley wrote:
> Bill Baxter Wrote:
> 
> 
>> I think there is a usage case for a function that acts virtual when 
>> called with an object instance, but static when called with just the 
>> class name.
>>
> 
> Definitely.
> 
>> It almost seems like you should be able to achieve it by just defining 
>> two versions of the method:
>>
>>      foo() { ... }
>>      static foo() { ... }
>>
>> If you think of the non-static version as having a hidden 'this' 
>> parameter, those two are not ambiguous according to standard overloading 
>> rules.
>>
>> On the other hand, you can pretty easily just make two versions of the 
>> function to achieve much the same thing, and just have the virtual 
>> version call the static version.
>>
>>      static Foo() {}
>>      foo() { Foo(); }
>>
>> Then if you have an object instance you can call inst.foo() and 
>> otherwise you can call Klass.Foo().
>>
>> --bb
> 
> I've done something similar in c++
> 
> class CFoo : public CBase
> {
>    public:
>    static const wchar_t *StaticTag()
>    {
>       static const wchar_t tag[] = L"foo";
>       return tag;
>    }
>    static CBase *StaticCreate()
>    {
>       return new CFoo;
>    }
> 
>    virtual const wchar_t *VirtualTag() { return StaticTag(); }
>    virtual CBase VirtualCreate() { return StaticCreate(); }
> }
> 
> I was reading xml and creating a tree of objects with the aid of a factory that had an STL map that mapped string to object creator.
> 
> You would register with the factory using:
>    pFactory->Register(CFoo::StaticTag(), CFoo::StaticCreator);
> 
> I had a GUI that made new nodes like this:
> 
>    CFoo *pFoo = CFoo::StaticCreator();
> 
> So far we are using statics, but when I want to write the tree back to xml I need virtuals.
> 
> void WriteXml(CBase *pRoot)
> {
>    printf("<%s>\n", pRoot->VirtualTag());
> 
>    // foreach child of pRoot
>    {
>       WriteXml(child);
>    }
> 
>    printf("<\\%s>\n", pRoot->VirtualTag());
> }
> 
> It worked but I had about 30 node types in a single schema and I had several schemas. I don't like the extra baggage of declaring separate static and virtual versions just because the language doesn't have virtual statics. (Evil C style macros to the rescue :-) )

Seems like it should be possible for the compiler to realize when you're 
not using 'this' in a method and create the vtable entry for the 
function sans hidden 'this' parameter.  Then it could make such a 
function callable via either Class.method or instance.method syntax.

--bb



More information about the Digitalmars-d mailing list