Can we have a static virtual functions? If not, then WHY? [duplicate]
Asked Answered
E

2

69

Possible Duplicate:
C++ static virtual members?

Can we have a static virtual functions? If not, then WHY?

class X
{
public:
       virtual static void fun(){} // Why we cant have static virtual function in C++?
};
Eureka answered 25/3, 2012 at 18:54 Comment(1)
One possible solution is to make a static method (but not virtual) in base class and make it call equivalent static method in Derived class. This way you still maintain encapsulation and polymorphism.Joashus
C
71

No, because it doesn't make any sense in C++.

Virtual functions are invoked when you have a pointer/reference to an instance of a class. Static functions aren't tied to a particular instance, they're tied to a class. C++ doesn't have pointers-to-class, so there is no scenario in which you could invoke a static function virtually.

Communication answered 25/3, 2012 at 18:56 Comment(23)
"Doesn't make any sense"? What about class methods in Python?Majorette
@Mehrdad: I don't know Python. Could you elaborate?Communication
https://mcmap.net/q/100014/-what-is-the-purpose-of-class-methodsMajorette
@Mehrdad: Ok, but in what context would they invoked virtually?Communication
https://mcmap.net/q/17853/-what-is-the-difference-between-staticmethod-and-classmethod-in-pythonMajorette
@Mehrdad - The question is tagged as (and specifically mentions) C++. It this context it indeed does not make sense.Unclose
@Mehrdad: Ok, but how would that ever translate into C++, given that there's no such thing as a pointer-to-class, only pointer-to-instance?Communication
The language could easily decide to add a static virtual function table for each classOeo
@Attila: I used to also say it doesn't "make sense", but I think that's a little too strong. It would certainly make sense if the language was implemented that way -- it just doesn't happen to be.Majorette
@Inverse: But what would that mean? In what context would you ever be in a position to virtually invoke a static function?Communication
@OliCharlesworth: When you have some sort of factory (e.g. a virtual constructor), I think it might make sense.Majorette
@Mehrdad: Yes, it would. But an essential prerequisite would then be the notion of a "pointer-to-class".Communication
@OliCharlesworth: Right. And there's no reason that couldn't exist -- it just doesn't happen to. But it certainly makes sense (and would be useful).Majorette
@Mehrdad: Absolutely agreed. My answer was written on the premise that pointers-to-class don't exist; I'll update it to make that explicit.Communication
@OliCharlesworth: Ok that makes more sense then. :PMajorette
So how would we impose (hence virtual) derived class on having an implemented, the class specific (hence static) method?Unable
@wiktus239: Given the constraints of C++, in what context would it be useful to impose this?Communication
Given the constraints of C++ it's invalid. However, the context that it may find its use is to have one abstract class dictate derived to be having static methods, with implementation suitable for the class.Unable
Respectfully, virtual static members do make sense for some uses and for some people. @OliverCharlesworth, consider rephrasing your answer or elaborating more. Yes, I realize it was accepted, but, well - the way it stands it is not true.Croatia
@Croatia - This was already rephrased in response to the comments discussion - it doesn't make sense in C++ because C++ doesn't have pointers/references-to-class (so there would be no way to leverage static polymorphism).Communication
You can call a static function on an object if you want, right? So in that case, you could use a vtable to determine which version of the function you would want to call. It especially makes sense when called from inside a non-static member function of the class itself.Gordon
Imagine an implementation where vtables are lists of function pointers, one table per class, some functions taking a 'this' pointer and some not. Object of the class receive the class vtable pointer when instantiated. The class vtable could still be referred to statically using the syntax class::static_method(). This could make sense implementation-wise. But a problem is that C++ does not have metadata "pointers to types" it only has "pointers to objects" so the usefulness might be limited; you'd need the fully resolved type before calling the method, reducing the value of virtual methodsRocket
What if I just want to use the function as a normal static function sometimes, but I also want the polymorphism when I am using it inside my class hierarchy?Staghound
H
9

That would make no sense. The point of virtual member functions is that they are dispatched based on the dynamic type of the object instance on which they are called. On the other hand, static functions are not related to any instances and are rather a property of the class. Thus it makes no sense for them to be virtual. If you must, you can use a non-static dispatcher:

struct Base
{
    static void foo(Base & b) { /*...*/ }

    virtual ~Base() { }
    virtual void call_static() { foo(*this); /* or whatever */ }
};

struct Derived : Base
{
     static void bar(int a, bool b) { /* ... */ }

     virtual void call_static() { bar(12, false); }
};

Usage:

Base & b = get_instance();
b.call_static();   // dispatched dynamically

// Normal use of statics:
Base::foo(b);
Derived::bar(-8, true);
Hellman answered 25/3, 2012 at 18:58 Comment(9)
You keep saying it "makes no sense" but the example you provide shows it could be a reasonable thing for a language to decide to support -- calling a static function in a derived class.Oeo
@Oeo what else could Base be at runtime except Base?Homework
It can have a sense if the function is pure virtual WITH a body. Then the compiler would errors if you don't overload it in your derived class. Think of a getInstance() function for example for making singleton. You might want to have a contract that says every class that derives from this Base must have a getInstance(). You want the compiler to check that for you.Irrawaddy
Is every C++ question on SO answered with "because it makes no sense"? I just created a virtual method because it had to be overridden, then I realised it didn't (and really mustn't) touch any instance data so added static to that, and that's how I ended up on this page. This answer provides a workaround (+1), but fails to answer the question because "it makes no sense" is just plain wrong.Video
@sh1: I happen to disagree. The question may sound sensible if you only just heard the words "C++", "class" and "virtual", but once you have a grasp on the object model of the language, it rapidly becomes clear that it isn't. Perhaps the difference in perception of SO is in how much background and preparation you expect from a question.Hellman
static doesn't just mean that it can be called without an instance of the class; it's also a promise that it will not access this. It somewhat approximates a pure function (like constexpr, which apparently also prohibits virtual). A function can be both pure (in the mathematical sense) and also virtual. C++ merely mandates that such a function receive a spurious this pointer which takes away the possibility of imposing the static contract on derived classes.Video
@sb1 you can const qualify such a method, which is a more conventional way of hinting purityMosier
Just wanted to show some support for sh1. It "wouldn't make sense" if c++ was the super strict each-keyword-means-one-thing always language many devs imply, but it really isn't. While the implementation of static virtual obviously would not work the same way normal static would, there is more than one part to what "virtual" does. In this case, he's looking for a compiler error if a static function is not defined. The compiler could easily do this while ignoring vtables. Versatile verbs are real.Continuation
I ran into this, and I think it could make sense even for C++. Basically the non-static dispatcher could be built into the language: static virtual foo(...) could create a vtable entry similar to call_foo(...) in the vtable with the implementation of calling the class's static foo(...). This would allow getting access to foo()... that is appropriate for the instance. E.g. instance->foo(...) while also allowing Class::foo(...) to also work.Migrate

© 2022 - 2024 — McMap. All rights reserved.