2
\$\begingroup\$

This is a header file for my bezier curve utility and several of BezierCurve2D's methods return newly created arrays of Point2D objects.

Should I create (using new) and delete objects in the same scopes? Should I have these methods receive a pre-allocated space of Point2Ds?

#ifndef BEZIER_UTILITY_H
#define BEZIER_UTILITY_H

class Point2D {
public:
    double X;
    double Y;
    Point2D();
    Point2D(double X, double Y);
    void set(double X_p, double Y_p);
    void set(Point2D* point_p);
};

class BezierBase {
protected:
    int values_length;
    double* temp_space;
    int temp_space_bytes;
    double* interp (double t, double* values);
public:
    BezierBase(int values_length);
    ~BezierBase();
};

class BezierCurve2D: public BezierBase {
private:
    double* Xs;
    double* Ys;
    double calc_dist (double x1, double x2, double y1, double y2);
    Point2D* linear_raster (double* values, int max_results, double goal_dist, double tolerance);
public:
    BezierCurve2D(double* x_values, double* y_values, int values_length);
    Point2D* rasterize (int max_results, double goal_dist, double tolerance);
    Point2D* rasterizeToX (int max_results, double goal_dist, double tolerance);
    Point2D* rasterizeToY (int max_results, double goal_dist, double tolerance);
    Point2D* getT (double t);
    double measure (double segment_dist, double tolerance);
};

#endif
\$\endgroup\$
3
\$\begingroup\$

Raw memory management should be incredibly rare and a last resort.

Your best bet will be some kind of container that can manage the memory for you. Returning a pointer to an allocated chunk of memory has all kinds of problems (who owns it and thus should delete[] it? what if you forget to release it? what about exception safety? etc).

In your situation, std::vector is almost certainly the right choice. It has essentially the same performance as a raw array if it's used wisely, and it gives pleasant, safe value semantics to an otherwise dangerous dynamic allocation.

In addition to the standard containers, it can also be valuable to know about std::shared_ptr and std::unique_ptr1. They give ownership semantics to memory allocations and facilitate safe handling of dynamically allocated memory. More plainly, they allow for the automatic releasing (e.g. delete or delete[]ing) of a memory allocation when the smart pointer (or all of the smart pointers in the case of std::shared_ptr) goes out of scope scope.


1 If you cannot use C++11, there are also some Boost smart pointers that do not require C++11.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.