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;
}

Reply via email to