C++ static virtual members?

virtual static c#
c++ override static method
ue4 static virtual
private virtual function c++
c++ override static member
c virtual member
c++ static member variable
why use virtual functions

Is it possible in C++ to have a member function that is both static and virtual? Apparently, there isn't a straightforward way to do it (static virtual member(); is a compile error), but is there at least a way to achieve the same effect?

I.E:

struct Object
{
     struct TypeInformation;

     static virtual const TypeInformation &GetTypeInformation() const;
};

struct SomeObject : public Object
{
     static virtual const TypeInformation &GetTypeInformation() const;
};

It makes sense to use GetTypeInformation() both on an instance (object->GetTypeInformation()) and on a class (SomeObject::GetTypeInformation()), which can be useful for comparisons and vital for templates.

The only ways I can think of involves writing two functions / a function and a constant, per class, or use macros.

Any other solutions?


No, there's no way to do it, since what would happen when you called Object::GetTypeInformation()? It can't know which derived class version to call since there's no object associated with it.

You'll have to make it a non-static virtual function to work properly; if you also want to be able to call a specific derived class's version non-virtually without an object instance, you'll have to provide a second redunduant static non-virtual version as well.

Can static functions be virtual in C++?, In C++, a static member function of a class cannot be virtual. For example, below program gives compilation error. C ++ static virtual members? Is it possible in C++ to have a member function that is both static and virtual? Apparently, there isn't a straightforward way to do it (static virtual member(); is a compile error), but is there at least a way to achieve the same effect? I.E: struct


Many say it is not possible, I would go one step further and say it is not meaningfull.

A static member is something that does not relate to any instance, only to the class.

A virtual member is something that does not relate directly to any class, only to an instance.

So a static virtual member would be something that does not relate to any instance or any class.

Why can't we declare static function as virtual 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  Static data members are subject to class-member access rules, so private access to static data members is allowed only for class-member functions and friends. These rules are described in Member-Access Control .


I ran into this problem the other day: I had some classes full of static methods but I wanted to use inheritance and virtual methods and reduce code repetition. My solution was:

Instead of using static methods, use a singleton with virtual methods.

In other words, each class should contain a static method that you call to get a pointer to a single, shared instance of the class. You can make the true constructors private or protected so that outside code can't misuse it by creating additional instances.

In practice, using a singleton is a lot like using static methods except that you can take advantage of inheritance and virtual methods.

Virtual Static Idiom, The Virtual Static Idiom is a very simple technique used in C++ to make static methods virtual. you have to pass a callback function into a system call, typical practice in Windows. Standard 'C'-style callbacks are done with (void(*)(void*)). A static member is shared by all objects of the class. All static data is initialized to zero when the first object is created, if no other initialization is present. We can't put it in the class definition but it can be initialized outside the class as done in the following example by redeclaring the static variable, using the scope resolution operator :: to identify which class it belongs to. Let us try the following example to understand the concept of static data members −


It is possible!

But what exactly is possible, let's narrow down. People often want some kind of "static virtual function" because of duplication of code needed for being able to call the same function through static call "SomeDerivedClass::myfunction()" and polymorphic call "base_class_pointer->myfunction()". "Legal" method for allowing such functionality is duplication of function definitions:

class Object
{
public:
    static string getTypeInformationStatic() { return "base class";}
    virtual string getTypeInformation() { return getTypeInformationStatic(); }
}; 
class Foo: public Object
{
public:
    static string getTypeInformationStatic() { return "derived class";}
    virtual string getTypeInformation() { return getTypeInformationStatic(); }
};

What if base class has a great number of static functions and derived class has to override every of them and one forgot to provide a duplicating definition for virtual function. Right, we'll get some strange error during runtime which is hard to track down. Cause duplication of code is a bad thing. The following tries to resolve this problem (and I want to tell beforehand that it is completely type-safe and doesn't contain any black magic like typeid's or dynamic_cast's :)

So, we want to provide only one definition of getTypeInformation() per derived class and it is obvious that it has to be a definition of static function because it is not possible to call "SomeDerivedClass::getTypeInformation()" if getTypeInformation() is virtual. How can we call static function of derived class through pointer to base class? It is not possible with vtable because vtable stores pointers only to virtual functions and since we decided not to use virtual functions, we cannot modify vtable for our benefit. Then, to be able to access static function for derived class through pointer to base class we have to store somehow the type of an object within its base class. One approach is to make base class templatized using "curiously recurring template pattern" but it is not appropriate here and we'll use a technique called "type erasure":

class TypeKeeper
{
public:
    virtual string getTypeInformation() = 0;
};
template<class T>
class TypeKeeperImpl: public TypeKeeper
{
public:
    virtual string getTypeInformation() { return T::getTypeInformationStatic(); }
};

Now we can store the type of an object within base class "Object" with a variable "keeper":

class Object
{
public:
    Object(){}
    boost::scoped_ptr<TypeKeeper> keeper;

    //not virtual
    string getTypeInformation() const 
    { return keeper? keeper->getTypeInformation(): string("base class"); }

};

In a derived class keeper must be initialized during construction:

class Foo: public Object
{
public:
    Foo() { keeper.reset(new TypeKeeperImpl<Foo>()); }
    //note the name of the function
    static string getTypeInformationStatic() 
    { return "class for proving static virtual functions concept"; }
};

Let's add syntactic sugar:

template<class T>
void override_static_functions(T* t)
{ t->keeper.reset(new TypeKeeperImpl<T>()); }
#define OVERRIDE_STATIC_FUNCTIONS override_static_functions(this)

Now declarations of descendants look like:

class Foo: public Object
{
public:
    Foo() { OVERRIDE_STATIC_FUNCTIONS; }
    static string getTypeInformationStatic() 
    { return "class for proving static virtual functions concept"; }
};

class Bar: public Foo
{
public:
    Bar() { OVERRIDE_STATIC_FUNCTIONS; }
    static string getTypeInformationStatic() 
    { return "another class for the same reason"; }
};

usage:

Object* obj = new Foo();
cout << obj->getTypeInformation() << endl;  //calls Foo::getTypeInformationStatic()
obj = new Bar();
cout << obj->getTypeInformation() << endl;  //calls Bar::getTypeInformationStatic()
Foo* foo = new Bar();
cout << foo->getTypeInformation() << endl; //calls Bar::getTypeInformationStatic()
Foo::getTypeInformation(); //compile-time error
Foo::getTypeInformationStatic(); //calls Foo::getTypeInformationStatic()
Bar::getTypeInformationStatic(); //calls Bar::getTypeInformationStatic()

Advantages:

  1. less duplication of code (but we have to call OVERRIDE_STATIC_FUNCTIONS in every constructor)

Disadvantages:

  1. OVERRIDE_STATIC_FUNCTIONS in every constructor
  2. memory and performance overhead
  3. increased complexity

Open issues:

1) there are different names for static and virtual functions how to solve ambiguity here?

class Foo
{
public:
    static void f(bool f=true) { cout << "static";}
    virtual void f() { cout << "virtual";}
};
//somewhere
Foo::f(); //calls static f(), no ambiguity
ptr_to_foo->f(); //ambiguity

2) how to implicitly call OVERRIDE_STATIC_FUNCTIONS inside every constructor?

Inheritance, A virtual function allows derived classes to replace the implementation provided by Pseudo-code (not C++, not C) for a static table defined within file Base.cpp  A static member function cannot be declared with the keywords virtual, const, volatile,orconst volatile. A static member function can access only the names ofstatic members, enumerators, and nested types of the class in whichit is declared. Suppose a static member function f()isa member of class X. The static member function f()cannotaccess the nonstatic members Xor the nonstatic membersof a base class of X.


While Alsk has already given a pretty detailed answer, I'd like to add an alternative, since I think his enhanced implementation is overcomplicated.

We start with an abstract base class, that provides the interface for all the object types:

class Object
{
public:
    virtual char* GetClassName() = 0;
};

Now we need an actual implementation. But to avoid having to write both the static and the virtual methods, we will have our actual object classes inherit the virtual methods. This does obviously only work, if the base class knows how to access the static member function. So we need to use a template and pass the actual objects class name to it:

template<class ObjectType>
class ObjectImpl : public Object
{
public:
    virtual char* GetClassName()
    {
        return ObjectType::GetClassNameStatic();
    }
};

Finally we need to implement our real object(s). Here we only need to implement the static member function, the virtual member functions will be inherited from the ObjectImpl template class, instantiated with the name of the derived class, so it will access it's static members.

class MyObject : public ObjectImpl<MyObject>
{
public:
    static char* GetClassNameStatic()
    {
        return "MyObject";
    }
};

class YourObject : public ObjectImpl<YourObject>
{
public:
    static char* GetClassNameStatic()
    {
        return "YourObject";
    }
};

Let's add some code to test:

char* GetObjectClassName(Object* object)
{
    return object->GetClassName();
}

int main()
{
    MyObject myObject;
    YourObject yourObject;

    printf("%s\n", MyObject::GetClassNameStatic());
    printf("%s\n", myObject.GetClassName());
    printf("%s\n", GetObjectClassName(&myObject));
    printf("%s\n", YourObject::GetClassNameStatic());
    printf("%s\n", yourObject.GetClassName());
    printf("%s\n", GetObjectClassName(&yourObject));

    return 0;
}

Addendum (Jan 12th 2019):

Instead of using the GetClassNameStatic() function, you can also define the the class name as a static member, even "inline", which IIRC works since C++11 (don't get scared by all the modifiers :)):

class MyObject : public ObjectImpl<MyObject>
{
public:
    // Access this from the template class as `ObjectType::s_ClassName` 
    static inline const char* const s_ClassName = "MyObject";

    // ...
};

C++ Tutorial: Static Variables and Static Class Members, C functions declared static within a module may only be called by other as virtual but care must be taken not to declare a static member function as virtual. Static member functions are not associated with any object. When called, they have no this pointer. Static member functions cannot be virtual, const, or volatile. The address of a static member function may be stored in a regular pointer to function, but not in a pointer to member function. Static data members. Static data members are not associated with any object.


static members, virtual member functions · pure virtual functions and abstract classes are independent variables with static or thread (since C++11) storage  Static member variables. C++ introduces two more uses for the static keyword when applied to classes: static member variables, and static member functions. Fortunately, these uses are fairly straightforward. We’ll talk about static member variables in this lesson, and static member functions in the next.


virtual function specifier, default member initializer(C++11) move assignment operator(C++11) The virtual specifier specifies that a non-static member function is  Virtual Function in C++ A virtual function is a member function which is declared within a base class and is re-defined(Overriden) by a derived class. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class’s version of the function.


Virtual Functions, In C++, dynamic binding is supported by the mechanism of virtual functions. be global or static because, by definition , a virtual function is a member function of  Static variables have a property of preserving their value even after they are out of their scope! Hence, static variables preserve their previous value in their previous scope and are not initialized again in the new scope. static data_type var_name = var_value; Following are some interesting facts about static variables in C.