#include <cstddef>
#include <iostream>
#include <vector>
class Field;
class Vector3d
{
friend class Field;
public:
Vector3d() : components_(new double[3]) {}
~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];
}
double & operator()(const std::size_t index) { return components_[index]; }
private:
Vector3d(double *ptr) : components_(ptr) {};
double *components_;
};
class Field
{
public:
Field(std::size_t size);
~Field();
Vector3d & operator()(const std::size_t index) { return *(vectors_[index]); }
private:
std::vector<double> components_;
std::vector<Vector3d *> vectors_;
};
Field::Field(std::size_t size)
: components_(std::vector<double>(3 * size))
// the line below is still evil in a subtle way, see below
, vectors_(std::vector<Vector3d *>(size, new Vector3d(0)))
{
double *ptr = &components_[0];
for (auto it = vectors_.begin(); it != vectors_.end(); ++it)
{
(*it)->components_ = ptr;
ptr += 3;
}
}
Field::~Field()
{
for (auto it = vectors_.begin(); it != vectors_.end(); ++it)
(*it)->components_ = 0;
}
int main(int argc, char *argv[])
{
Field field(2);
std::cout << field(0)(0) << " " << field(1)(0) << std::endl;
field(0)(0) = 5;
std::cout << field(0)(0) << " " << field(1)(0) << std::endl;
// both were changed because you initialized every single vectors_ entry with a pointer
// to the same Vector3d object.
return 0;
}