#include <cstddef>
#include <iostream>
#include <vector>
class Field;
class Vector3d
{
// this is not really bad practice...
// there can be valid reasons but you should really think twice
// before declaring anything as a friend
// in your case you are doing really bad things with it
friend class Field;
public:
// on its own this is not wrong
// but in your case there are two issues:
// 1. you want contigous memory, but the new creates these 3 doubles somewhere on the heap, not inside your object
// 2. later on you will overwrite components_ with another pointer which makes this stuff leak
Vector3d() : components_(new double[3]) {}
// see point 2 above: in the destructor components_ would be freed
// while the addresses it points to are actually not freeable
// EVEN WORSE: this is pseudo fixed in the Field destructor which sets all components_ to 0, so delete[] does nothing
~Vector3d() { delete[] components_; }
Vector3d(const Vector3d &v) : components_(new double[3])
{
components_[0] = v.components_[0];
components_[1] = v.components_[1];
components_[2] = v.components_[2];
}
// usually one would overload the [] operator for this, but that is not a real issue
// the const on the index is a bit useless here
// speaking of which... you should overload the operator twice, because currently there is no const version of it
double & operator()(const std::size_t index) { return components_[index]; }
// like so:
// double operator()(std::size_t index) const { return componens_[index]; }
private:
// I can see the intention for this constructor
// and actually it would be a better approach then the stuff above
Vector3d(double *ptr) : components_(ptr) {};
// I already suggested several methods to store the double's inline instead of on the heap
double *components_;
};
class Field
{
public:
Field(std::size_t size);
~Field();
// again: useless const and no const version of the operator
Vector3d & operator()(const std::size_t index) { return *(vectors_[index]); }
private:
std::vector<double> components_;
// what the actual fsck?
std::vector<Vector3d *> vectors_;
};
Field::Field(std::size_t size)
: components_(std::vector<double>(3 * size)) // actually not that bad... but the context...
, vectors_(std::vector<Vector3d *>(size, new Vector3d(0))) // wtf?
{
double *ptr = &components_[0];
for (auto it = vectors_.begin(); it != vectors_.end(); ++it)
{
// seriosly?
// the old memory allocated with new[] is totally screaming for its life here
(*it)->components_ = ptr;
ptr += 3;
}
}
Field::~Field()
{
for (auto it = vectors_.begin(); it != vectors_.end(); ++it)
(*it)->components_ = 0; // what a dirty hack fix
}
int main(int argc, char *argv[])
{
Field field(2);
Vector3d &v = field(1);
v(2) = 5;
Vector3d v2 = v;
v2(2) = 2;
std::cout << field(1)(2) << std::endl;
return 0;
}