Getting rid of dynamic polymorphism and classes

Tommi tommitissari at hotmail.com
Thu Nov 8 09:27:40 PST 2012


I just started watching that:
http://cppnow.org/session/value-semantics-and-concepts-based-polymorphism/

..and it got me thinking, couldn't we just get rid of dynamic 
polymorphism and classes altogether? Doesn't static polymorphism 
through the use of duck typing and member function delegates 
provide all that we need? This way we wouldn't have the nasty 
coupling of types which inheritance causes. Here's a C++ example:
(I'm sure it would look nicer with D's syntax)

// Canvas.h
#pragma once

#include <functional>
#include <type_traits>
#include <utility>
#include <vector>

class Canvas
{
private:
     struct Shape // Represents an interface
     {
         std::function<void (int x, int y)>        resize;
         std::function<void (int x, int y)>        moveTo;
         std::function<bool (int r, int g, int b)> draw;
     };

public:
     template <typename S>
     auto addShape(S& s)
     -> typename std::enable_if<
         std::is_same<decltype(s.resize(1, 1)), void>::value &&
         std::is_same<decltype(s.moveTo(1, 1)), void>::value &&
         std::is_same<decltype(s.draw(1, 1, 1)), bool>::value
     >::type
     {
         Shape shape;

         shape.resize = [&](int x, int y)
                           { return s.resize(x, y); };
						
         shape.moveTo = [&](int x, int y)
                           { return s.moveTo(x, y); };
						
         shape.draw = [&](int r, int g, int b)
                         { return s.draw(r, g, b); };

         _shapes.emplace_back(std::move(shape));
     }

     Shape& getShape(size_t idx)
     {
         return _shapes[idx];
     }

private:
     std::vector<Shape> _shapes;
};


// Circle.h
#pragma once

#include <conio.h>

class Circle
{
public:
     void resize(int x, int y)
     {
         _cprintf("Circle resized to %d %d\n", x, y);
     }

     void moveTo(int x, int y)
     {
         _cprintf("Circle moved to %d %d\n", x, y);
     }

     bool draw(int r, int g, int b)
     {
         _cprintf("Circle drawn with color %d %d %d\n", r, g, b);
         return true;
     }
};


// Rectangle.h
#pragma once

#include <conio.h>

class Rectangle
{
public:
     void resize(int x, int y)
     {
         _cprintf("Rectangle resized to %d %d\n", x, y);
     }

     void moveTo(int x, int y)
     {
         _cprintf("Rectangle moved to %d %d\n", x, y);
     }

     bool draw(int r, int g, int b)
     {
         _cprintf("Rectangle drawn with color %d %d %d\n",r,g,b);
         return true;
     }
};


// main.cpp
int main()
{
     Canvas canvas;
     Rectangle rectangle;
     Circle circle;

     canvas.addShape(rectangle);
     canvas.addShape(circle);

     canvas.getShape(0).resize(5, 5);
     canvas.getShape(0).moveTo(2, 3);
     canvas.getShape(0).draw(1, 12, 123);

     canvas.getShape(1).resize(10, 10);
     canvas.getShape(1).moveTo(4, 5);
     canvas.getShape(1).draw(50, 0, 50);

     _getch();
     return 0;
}

// Prints:
Rectangle resized to 5 5
Rectangle moved to 2 3
Rectangle drawn with color 1 12 123
Circle resized to 10 10
Circle moved to 4 5
Circle drawn with color 50 0 50



More information about the Digitalmars-d mailing list