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