From 5f253838910b7483fb3a83cbeae533a36289ccea Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Sun, 9 Feb 2025 20:31:58 -0500 Subject: [PATCH] Added a small micro example of the problem with SFML's use of const on drawable virtual functions which shows the _real_ reason they did this is because of a poor design decision to make both Drawable and RenderTarget equally in charge of drawing the other. AKA the 'Deadly Embrace' design flaw. --- meson.build | 4 ++++ sfml-const/constness.cpp | 24 ++++++++++++++++++++++++ sfml-const/constness.hpp | 18 ++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 sfml-const/constness.cpp create mode 100644 sfml-const/constness.hpp diff --git a/meson.build b/meson.build index 80ce1c4..10b19e6 100644 --- a/meson.build +++ b/meson.build @@ -49,3 +49,7 @@ executable('rvo_test', [ ], override_options: exe_defaults, dependencies: dependencies) + +executable('constness', 'sfml-const/constness.cpp', + override_options: exe_defaults, + dependencies: dependencies) diff --git a/sfml-const/constness.cpp b/sfml-const/constness.cpp new file mode 100644 index 0000000..9d88955 --- /dev/null +++ b/sfml-const/constness.cpp @@ -0,0 +1,24 @@ +#include +#include "constness.hpp" + +using std::cout; + +void RenderTarget::draw(const Drawable& drawable) { + drawable.draw(*this); +} + +void Shape::draw(const RenderTarget& target) const { + cout << "shape draw\n"; +} + +using std::cout; + +int main() { + + RenderTarget target; + Shape shape; + + target.draw(shape); + + return 0; +} diff --git a/sfml-const/constness.hpp b/sfml-const/constness.hpp new file mode 100644 index 0000000..2ced61c --- /dev/null +++ b/sfml-const/constness.hpp @@ -0,0 +1,18 @@ +#pragma once + +class Drawable; + +class RenderTarget { + public: + void draw(const Drawable& drawable); +}; + +class Drawable { + public: + virtual void draw(const RenderTarget& target) const = 0; +}; + +class Shape : public Drawable { + public: + void draw(const RenderTarget& target) const override; +};