the inheritance of functions and return types in c

Returning interface is fine in general:

class Ray;

struct Intersection
{
    virtual ~Intersection() = default;
    virtual double modulate_intensity(double intensity) = 0;
};
struct Intersection_Polygon : Intersection
{
    double modulate_intensity(double intensity) override {/**/}
};
struct Intersection_Polyhedron : Intersection
{
    double modulate_intensity(double intensity) override {/**/}
};

struct Object
{
    virtual ~Object() = default;
    virtual std::shared_ptr<Intersection> get_intersection(const Ray&) = 0;
};

struct Polygon : Object
{
    std::shared_ptr<Intersection> get_intersection(const Ray&) override {
        return std::make_shared<Intersection_Polygon>();
    }
};
struct Polyhedron : Object
{
    std::shared_ptr<Intersection> get_intersection(const Ray&) override {
        return std::make_shared<Intersection_Polyhedron>();
    }
};

Return type can be improved with covariance, but C++ only handle it for references and (non-smart) pointers. So it requires some boiler plate to simulate it for smart pointers:

struct Object
{
    virtual ~Object() = default;
    std::shared_ptr<Intersection> get_intersection(const Ray& ray)
    {
        return std::shared_ptr<Intersection>{get_intersection_ptr(ray)};
    }
protected:
    virtual Intersection* get_intersection_ptr(const Ray&) = 0;
};

struct Polygon : Object
{
    std::shared_ptr<Intersection_Polygon> get_intersection(const Ray& ray)
    {
        return std::shared_ptr<Intersection_Polygon>{get_intersection_ptr(ray)};
    }
protected:
    Intersection_Polygon* get_intersection_ptr(const Ray&) override {
        return new Intersection_Polygon();
    }
};

template (possibly CRTP) might help to factorize boiler plate:

template <typename IntersectionType>
struct ObjectT : Object
{
    std::shared_ptr<IntersectionType> get_intersection(const Ray& ray)
    {
        return std::shared_ptr<IntersectionType>{get_intersection_ptr(ray)};
    }
protected:
    IntersectionType* get_intersection_ptr(const Ray&) override {
        return new IntersectionType();
    }
};

struct Polygon : ObjectT<Intersection_Polygon> {};
struct Polyhedron : ObjectT<Intersection_Polyhedron> {};

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top