c++ - Class - User Defined Smart Array with dynamic size -
i writing following array (class) increases size when index of array bigger size of array. i know vectors has array. code looks this:
#include <iostream> using namespace std; class array { public: array():_array(new float[0]), _size(0){}; ~array() {delete[] _array;} friend ostream &operator<<(ostream&,const array&); float& operator[] (int index) { if(index>=_size) { float* newarray=new float[index+1]; for(int i=0;i<_size;++i) newarray[i]=_array[i]; for(int i=_size;i<index+1;++i) newarray[i]=0; delete[] _array; _array=newarray; _size=index+1; } return _array[index]; } private: float *_array; // pointer array int _size; // current size of array }; ostream &operator << ( ostream &out, const array& obj) // overloading operator<< print array { cout << "array:\n\n"; (int i=0;i<obj._size;++i) { cout << obj._array[i]; if(i+1!=obj._size) cout << ", "; } cout << ".\n"; return out; } int main() { array customarray; customarray[2] = customarray[1] = customarray[0] = 3.14; // **here problem** cout << customarray << endl; } everything ok, 0 warnings , 0 valgrind errors, output :
3.14, 3.14, 3.14. but i have write code ( in main ) way :
customarray[0] = customarray[1] = customarray[2] = 3.14; and it's 3 valgrind errors: address (some_address) 4 bytes inside block of size 8 free'd,
and output looks : 0, 0, 3.14.
unfortunately have write code work second way ( customarray[0] = customarray[1] = customarray[2] = 3.14; ) can guys ? in advance
you need resolve through use of proxy type holds reference array object , index passed operator[]. proxy type implicitly convertible float , assignable float, making accesses (mostly1) transparent.
we violate rule of 3 in case , implement copy-assignment operator assign value of 1 array element foo[0] = foo[1] works expected.
we need make following changes:
- rename existing
operator[], make private; used proxy type. - create new
operator[]returns value of proxy type. - write proxy type.
change 1, inside of array's definition:
friend class arrayelement; // arrayelement can use access() private: float& access(int index) { if(index>=_size) { float* newarray=new float[index+1]; for(int i=0;i<_size;++i) newarray[i]=_array[i]; for(int i=_size;i<index+1;++i) newarray[i]=0; delete[] _array; _array=newarray; _size=index+1; } return _array[index]; } change 2:
// inside of array public: arrayelement operator[](int index); // implementation outside of array arrayelement array::operator[](int index) { return arrayelement(*this, index); } change 3:
class arrayelement { friend class array; // array can use our private constructor private: arrayelement(array & array, int index) : array(array), index(index) { } public: // allows "foo[1] = 2" arrayelement const & operator=(float v) const { array.access(index) = v; return *this; } // violation of rule of three, makes sense in case. // allows "foo[1] = foo[2]" arrayelement const & operator=(arrayelement const & other) const { array.access(index) = other; return *this; } // allows "float x = foo[1]" operator float() const { return array.access(index); } private: array & array; int index; }; (minor final change, need forward declare arrayelement before definition of array.)
1 1 of caveats of approach using type-inference (auto in c++11) on array accesses:
auto x = an_array[1]; now x arrayelement instead of float , value observed change when an_array[1] changes. attempting assign different float value x change value in an_array[1] well, since x proxy value.
contrast general behavior of std::vector auto x = a_vector[0] result in x being element type of vector, , therefore hold independent copy of value stored in vector.
note, however, std::vector<bool> specialization follows approach i've given here (returning proxy object) , it have same auto caveat! take blessing on approach.
Comments
Post a Comment