While writing my first big project in C++, I encountered a problem which I wasn´t able to solve using google and documentation alone.
I cannot figure out, why this dynamic_cast fails, even though r is pointing to a MeshRenderer Object.
for (RenderEventConsumer* r : d->getConsumers())
{
    glUseProgram(mPickingShader->apiID);
    MeshRenderer* m = dynamic_cast<MeshRenderer*>(r); //returns nullptr
    if (m)
    {
        glUniform1ui(uPickingID, m->getOwner()->getID());
        m->getMesh()->getUtillityBuffer().draw();
    }
}
The class RenderEventConsumer has a virtual method and is a base of MeshRenderer.
class MeshRenderer : public Component {...}
class Component : public GameObject {...}
class GameObject : protected TickEventConsumer, protected RenderEventConsumer, protected PhysicsTickEventConsumer {...}
According to Visual Studio the vftable of r is correct.

PS: This is my first question on stackoverflow, please let me know if I violated any guideline or am missing relevant information.
EDIT: Although I know the answer now, I reproduced the error with a standalone example for clarity:
#include <vector>
#include <iostream>
class RenderEventConsumer
{
    virtual void onRender() {};
};
class RenderEventDispatcher
{
    std::vector<RenderEventConsumer*> mConsumers;
public:
    const std::vector<RenderEventConsumer*>& getConsumers()
    {
        return mConsumers;
    }
    void registerRenderEventConsumer(RenderEventConsumer* consumer)
    {
        mConsumers.push_back(consumer);
    }
};
class GameObject : protected RenderEventConsumer {}; //changing this to public fixes dynamic_cast
class Component : public GameObject {};
class MeshRenderer : public Component 
{
public:
    void setup(RenderEventDispatcher& d) 
    {
        d.registerRenderEventConsumer(this);
    }
    void onRender() override { }
};
int main()
{
    RenderEventDispatcher d;
    MeshRenderer* pt = new MeshRenderer();
    pt->setup(d);
    
    for (RenderEventConsumer* r : d.getConsumers())
    {
        MeshRenderer* m = dynamic_cast<MeshRenderer*>(r);
        if (m)
        {
            std::cout << "not nullptr\n";
        }
        else
        {
            std::cout << "nullptr\n";
        }
    }
}
 
    