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 Point2D
s?
#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
1 Answer 1
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_ptr
1. 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.