fork download
  1. #include <cstddef>
  2. #include <iostream>
  3. #include <iomanip>
  4.  
  5. class Matrix {
  6. protected:
  7. // Out proxy class.
  8. // Visible to children, for implementing.
  9. struct SubscriptProxy {
  10. virtual operator double&() = 0;
  11. virtual operator double*() = 0;
  12. virtual double& operator=(double) = 0;
  13. virtual double& operator[](size_t) = 0;
  14. virtual ~SubscriptProxy() = default;
  15. };
  16.  
  17. public:
  18. virtual SubscriptProxy& operator[](size_t i) = 0;
  19. virtual ~Matrix() = default;
  20.  
  21. virtual void out(std::ostream& str) const = 0;
  22. friend std::ostream& operator<<(std::ostream& str, const Matrix& m) {
  23. m.out(str);
  24. return str;
  25. }
  26. };
  27. std::ostream& operator<<(std::ostream& str, const Matrix& m);
  28.  
  29. // Resizing omitted for brevity.
  30. class OneDMatrix : public Matrix {
  31. double arr[5];
  32.  
  33. // Proxy for single element.
  34. class OneDProxy : public SubscriptProxy {
  35. double& elem;
  36.  
  37. operator double*() override { return &elem; }
  38. double& operator[](size_t) override { return elem; }
  39. public:
  40. OneDProxy(double& e) : elem(e) {}
  41.  
  42. operator double&() override { return elem; }
  43. double& operator=(double d) override {
  44. elem = d;
  45. return elem;
  46. }
  47. };
  48.  
  49. public:
  50. OneDMatrix() : arr{0} {}
  51.  
  52. // operator[] maintains a static pointer, to keep the return value alive and guarantee
  53. // proper cleanup.
  54. SubscriptProxy& operator[](size_t i) override {
  55. static OneDProxy* ret = nullptr;
  56.  
  57. if (ret) { delete ret; }
  58. ret = new OneDProxy(arr[i]);
  59. return *ret;
  60. }
  61.  
  62. void out(std::ostream& str) const override {
  63. for (size_t i = 0; i < 5; i++) {
  64. str << std::setw(4) << arr[i] << ' ';
  65. }
  66. str << std::endl;
  67. }
  68. };
  69.  
  70. // Resizing omitted for brevity.
  71. class TwoDMatrix : public Matrix {
  72. double arr[3][4];
  73.  
  74. // Proxy for array.
  75. class TwoDProxy : public SubscriptProxy {
  76. double* elem;
  77.  
  78. operator double&() override { return elem[0]; }
  79. double& operator=(double) override { return elem[0]; }
  80. public:
  81. TwoDProxy(double* e) : elem(e) {}
  82. operator double*() override { return elem; }
  83. double& operator[](size_t i) override { return elem[i]; }
  84. };
  85.  
  86. public:
  87. TwoDMatrix() : arr{{0}} {}
  88.  
  89. // operator[] maintains a static pointer, to keep the return value alive and guarantee
  90. // proper cleanup.
  91. SubscriptProxy& operator[](size_t i) override {
  92. static TwoDProxy* ret = nullptr;
  93.  
  94. if (ret) { delete ret; }
  95. ret = new TwoDProxy(arr[i]);
  96. return *ret;
  97. }
  98.  
  99. void out(std::ostream& str) const override {
  100. for (size_t i = 0; i < 3; i++) {
  101. for (size_t j = 0; j < 4; j++) {
  102. str << std::setw(4) << arr[i][j] << ' ';
  103. }
  104. str << '\n';
  105. }
  106. }
  107. };
  108.  
  109. int main() {
  110. // By pointer.
  111. Matrix* one = new OneDMatrix;
  112. Matrix* two = new TwoDMatrix;
  113.  
  114. (*one)[2] = 3;
  115. std::cout << *one << std::endl;
  116. delete one;
  117.  
  118. // -----
  119.  
  120. (*two)[0][1] = 1;
  121. (*two)[1][0] = 10;
  122. (*two)[2][2] = 100;
  123. std::cout << *two << std::endl;
  124. delete two;
  125.  
  126. // -----
  127.  
  128. //Directly.
  129. OneDMatrix oneone;
  130. oneone[2] = -3;
  131. std::cout << oneone << std::endl;
  132.  
  133. TwoDMatrix twotwo;
  134. twotwo[1][0] = -1;
  135. twotwo[0][1] = -10;
  136. twotwo[2][2] = -100;
  137. std::cout << twotwo << std::endl;
  138. }
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
   0    0    3    0    0 

   0    1    0    0 
  10    0    0    0 
   0    0  100    0 

   0    0   -3    0    0 

   0  -10    0    0 
  -1    0    0    0 
   0    0 -100    0