Search code examples
c++unreal-engine4

static inline in class inheritance


I am reading some of the Epic Games UnrealEngine4 source code and see couple of practices which make me wonder if I miss some of essential C++ magic.

  1. static inline member methods in class declaration.Here @dividebyzero user actually sheds very important info regarding the effect of using static inline,at least with GCC compiler - inline placement similar to how MACRO functions behave.

  2. Another interesting practice I can see is how UE4 creates interfaces for inheritance.Here is example based on how OpenGL backend module in UE4 looks like:

    class FOpenGLBase
    {
       public:
         static FORCEINLINE void UnmapBufferRange(GLenum Type, uint32 InOffset, uint32 InSize) UGL_REQUIRED_VOID 
    };
    

Where UGL_REQURED_VOID is replaced with default function body,which reports "unimplemented" method error if called on this base class.

Next come inheritance of the above class:

    struct FOpenGL3 : public FOpenGLBase
    {
        static FORCEINLINE void UnmapBuffer(GLenum Type)
        {
          glUnmapBuffer(Type);
        }
        static FORCEINLINE void UnmapBufferRange(GLenum Type, uint32 InOffset, uint32 InSize)
        {
           UnmapBuffer(Type);
        }
    };

I even didn't know it was possible for a struct to inherit from class and vice -versa.

I understand that static + inline makes it possible to generate unique function body per function call,which makes it possible to put different body but with same signature in subclass's declaration. But then I also wonder why one needs virtual inheritance for small methods if it is possible to override static inline methods in subclass just like this? Why such an approach is not common? (at least from my experience I find it uncommon)

PS: I wasn't sure if this question format is ok for SO or should be rather put in CodeReview site.


Solution

  • First of all, the post you refer to seems to be about static inline functions in the namespace scope. Your example has them in a class scope. There's a very big difference between these two scopes.

    In class scope, the static keyword makes the method callable on the class, instead of on an instance. So in this scope, there's a very real difference between static, static inline and just inline.

    Next, static methods in class scopes have nothing to do with inheritance, exactly because static members are part of the class rather than instances. Inheritance is only relevant for instances. To make this clear, consider how you would call UnmapBufferRange on either FOpenGLBase or FOpenGL3:

    FOpenGLBase::UnmapBufferRange(..); // Call the FOpenGLBase version
    FOpenGL3::UnmapBufferRange(..); // Call the FOpenGL3 version
    

    There's no inheritance because you couldn't even override it - you simply redefine it for another class. This effectively hides it, so it looks like inheritance but it's not the same!