Good way to structure a SDL project
I think that yes, the code can be structured somewhat better.
First of all, I'd tend to &quot;RAII all the things&quot;. Code like this at the end of main makes me extremely suspicious:
    SDL_DestroyWindow(window.getWindow());
    SDL_Quit();

I'd strongly prefer that those be handled in the destructor of some object so they happen automatically.
So, I'd rename CreateWindow to just Window. Then I'd add a destructor that called SDL_DestroyWindow, so it'll automatically clean itself up when it goes out of scope.
class Window {
public:
    Window(int x, int y, int w, int h, bool fullScreen = false) {
        pWindow = SDL_CreateWindow(&quot;&quot;, x, y, w, h, fullScreen);
        if (pWindow == nullptr)
            throw std::runtime_error(&quot;Unable to create window&quot;);
    }

    ~Window() { SDL_DestroyWindow(pWindow); }

    operator SDL_Window*() { return pWindow; }

private:
    SDL_Window *pWindow;
};

Likewise I'd add an Application class (or something on that order that calls SDL_Init in its ctor, and SDL_Quit(); in its dtor, so simply defining a variable of that type automatically initializes SDL, and cleans up before it goes out of scope.
class Application {
public:    
    Application() { 
        if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
        {
            std::stringstream buffer;
            buffer &lt;&lt; &quot;Could not intialize SDL properly: &quot; &lt;&lt; SDL_GetError();

            throw std::runtime_error(buffer.str());
        }        
    }

    ~Application() {
        SDL_Quit();
    }
};

...and of course, Renderer should clean up after itself as well:
    ~Renderer() { 
        SDL_DestroyRenderer(pRenderer);
    }

I'd also add definitions of copy assignment, move assignment, copy construction, and move construction to Renderer, Window and Application, so somebody won't accidentally do something nasty and breaking with them. In this case, they're probably move-only classes, so we'd do something on this order:
    Renderer(Renderer const &amp;) = delete;
    Renderer(Renderer &amp;&amp;other) { 
        pRenderer = other.pRenderer; 
        other.pRenderer = nullptr; 
    }
    Renderer &amp;operator=(Renderer const &amp;) = delete;
    Renderer &amp;operator=(Renderer &amp;&amp; other) { 
        pRenderer = other.pRenderer; 
        other.pRenderer = nullptr; 
        return *this;
    }

Window would probably be similar in this regard, and Application should probably delete all of them.
I'd also have each of the classes report problems with construction by throwing an exception, rather than leaving it to client code to detect the problem when (for example) it has failed to create a window.
    Window(int x, int y, int w, int h, bool fullScreen = false) {
        pWindow = SDL_CreateWindow(&quot;&quot;, x, y, w, h, fullScreen);
        if (pWindow == nullptr)
            throw std::runtime_error(&quot;Unable to create window&quot;);
    }
}

Rather than Events::handleEvents being passed a Boolean in a structure, I'd have it just return a value to indicate when the program should exit:
    bool handleEvents()
    {
        while (SDL_PollEvent(&amp;event))
        {
            if (event.type == SDL_QUIT)
                return false;
        }
        return true;
    }

I'd also put all of these in a namespace named something like sdl (or sdl2, or something on that order).
With that &quot;stuff&quot; in place, our main can shrink to something on this order:
int main(int argc, char* argv[])
{
    try {
        sdl::Application app;

        sdl::Window window(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1600, 1200);
        sdl::Renderer renderer(window);
        sdl::Events events;

        while (events.handleEvents())
        {
            renderer.clearScreen(255, 255, 255, 255);
            renderer.render();
            renderer.update();
        }
    }
    catch(std::exception const &amp;e) { 
        std::cerr &lt;&lt; e.what() &lt;&lt; &quot;\n&quot;;
    }
}

Although I haven't shown it above, I'd at least be tempted to require that a reference to an sdl::Application be passed to the ctor when you create an sdl::Window object. This assures that you've created an sdl::Application object first, thereby assuring that SDL is initialized before you try to create a window with it.