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