fork download
  1. #include <cstddef>
  2. #include <iostream>
  3. #include <vector>
  4.  
  5. class Field;
  6.  
  7. class Vector3d
  8. {
  9. friend class Field;
  10.  
  11. public:
  12. Vector3d() : components_(new double[3]) {}
  13. ~Vector3d() { delete[] components_; }
  14.  
  15. Vector3d(const Vector3d &v) : components_(new double[3])
  16. {
  17. components_[0] = v.components_[0];
  18. components_[1] = v.components_[1];
  19. components_[2] = v.components_[2];
  20. }
  21.  
  22. double & operator()(const std::size_t index) { return components_[index]; }
  23.  
  24. private:
  25. Vector3d(double *ptr) : components_(ptr) {};
  26. double *components_;
  27. };
  28.  
  29. class Field
  30. {
  31. public:
  32. Field(std::size_t size);
  33. ~Field();
  34.  
  35. Vector3d & operator()(const std::size_t index) { return *(vectors_[index]); }
  36.  
  37. private:
  38. std::vector<double> components_;
  39. std::vector<Vector3d *> vectors_;
  40. };
  41.  
  42. Field::Field(std::size_t size)
  43. : components_(std::vector<double>(3 * size))
  44. // the line below is still evil in a subtle way, see below
  45. , vectors_(std::vector<Vector3d *>(size, new Vector3d(0)))
  46. {
  47. double *ptr = &components_[0];
  48. for (auto it = vectors_.begin(); it != vectors_.end(); ++it)
  49. {
  50. (*it)->components_ = ptr;
  51. ptr += 3;
  52. }
  53. }
  54.  
  55. Field::~Field()
  56. {
  57. for (auto it = vectors_.begin(); it != vectors_.end(); ++it)
  58. (*it)->components_ = 0;
  59. }
  60.  
  61. int main(int argc, char *argv[])
  62. {
  63. Field field(2);
  64. std::cout << field(0)(0) << " " << field(1)(0) << std::endl;
  65.  
  66. field(0)(0) = 5;
  67.  
  68. std::cout << field(0)(0) << " " << field(1)(0) << std::endl;
  69.  
  70. // both were changed because you initialized every single vectors_ entry with a pointer
  71. // to the same Vector3d object.
  72.  
  73. return 0;
  74. }
Success #stdin #stdout 0s 3228KB
stdin
Standard input is empty
stdout
0 0
5 5