Alternatives to OOP in D
Peter C
peterc at gmail.com
Fri Nov 14 23:35:02 UTC 2025
On Friday, 14 November 2025 at 22:53:33 UTC, Sergey wrote:
> On Friday, 14 November 2025 at 22:45:59 UTC, Peter C wrote:
>> On Friday, 14 November 2025 at 06:35:23 UTC, monkyyy wrote:
>> An alternative choice for modelling polymorphism will shift
>> the priorities to something else all together.
>
> At least D did it right
If doing it right means D lets you choose whether to order the
meal delivered, or make it entirely yourself, then yes, it did it
right.
Here's the make it yourself way - for those don't have better
things to do with their life ;)
module myModule;
import core.stdc.stdio; // for printf, sprintf
import core.stdc.stdlib; // for malloc, free
import core.stdc.string; // for sprintf
struct Shape
{
ShapeVTable* vtable;
const(char)* description;
}
struct ShapeVTable
{
double function(Shape*) getArea;
}
struct Rectangle
{
Shape base;
double width;
double height;
}
struct Square
{
Shape base;
double side;
}
struct Circle
{
Shape base;
double radius;
}
struct Triangle
{
Shape base;
double base_len;
double height;
}
// Implementations
double Rectangle_getArea(Shape* s)
{
auto r = cast(Rectangle*)s;
return r.width * r.height;
}
double Square_getArea(Shape* s)
{
auto sq = cast(Square*)s;
return sq.side * sq.side;
}
double Circle_getArea(Shape* s)
{
auto c = cast(Circle*)s;
return 3.14159 * c.radius * c.radius;
}
double Triangle_getArea(Shape* s)
{
auto t = cast(Triangle*)s;
return 0.5 * t.base_len * t.height;
}
// Vtables
ShapeVTable rectangle_vtable = { &Rectangle_getArea };
ShapeVTable square_vtable = { &Square_getArea };
ShapeVTable circle_vtable = { &Circle_getArea };
ShapeVTable triangle_vtable = { &Triangle_getArea };
// Constructors
Rectangle* newRectangle(double w, double h)
{
auto r = cast(Rectangle*) malloc(Rectangle.sizeof);
r.base.vtable = &rectangle_vtable;
r.base.description = cast(const(char)*) malloc(50);
sprintf(cast(char*)r.base.description, "Rectangle
(width=%.0f, height=%.0f)", w, h);
r.width = w;
r.height = h;
return r;
}
Square* newSquare(double side)
{
auto sq = cast(Square*) malloc(Square.sizeof);
sq.base.vtable = &square_vtable;
sq.base.description = cast(const(char)*) malloc(30);
sprintf(cast(char*)sq.base.description, "Square (side=%.0f)",
side);
sq.side = side;
return sq;
}
Circle* newCircle(double radius)
{
auto c = cast(Circle*) malloc(Circle.sizeof);
c.base.vtable = &circle_vtable;
c.base.description = cast(const(char)*) malloc(30);
sprintf(cast(char*)c.base.description, "Circle
(radius=%.0f)", radius);
c.radius = radius;
return c;
}
Triangle* newTriangle(double base_len, double height)
{
auto t = cast(Triangle*) malloc(Triangle.sizeof);
t.base.vtable = &triangle_vtable;
t.base.description = cast(const(char)*) malloc(40);
sprintf(cast(char*)t.base.description, "Triangle (base=%.0f,
height=%.0f)", base_len, height);
t.base_len = base_len;
t.height = height;
return t;
}
int main()
{
Shape*[8] shapes;
shapes[0] = cast(Shape*) newRectangle(10, 5);
shapes[1] = cast(Shape*) newRectangle(20, 3);
shapes[2] = cast(Shape*) newSquare(7);
shapes[3] = cast(Shape*) newSquare(12);
shapes[4] = cast(Shape*) newCircle(5);
shapes[5] = cast(Shape*) newCircle(10);
shapes[6] = cast(Shape*) newTriangle(10, 4);
shapes[7] = cast(Shape*) newTriangle(6, 8);
double totalArea = 0.0;
printf("--- Mixed Shape Calculations ---\n\n");
printf("Shape | Area\n");
printf("------------------------------------+------\n");
foreach (i; 0 .. 8)
{
double area = shapes[i].vtable.getArea(shapes[i]);
printf("%-35s | %.0f\n", shapes[i].description, area);
totalArea += area;
}
printf("\nTotal Area of All Shapes: %.0f\n", totalArea);
foreach (i; 0 .. 8)
{
free(cast(void*) shapes[i].description);
free(shapes[i]);
}
return 0;
}
More information about the Digitalmars-d-learn
mailing list