#include <iostream>
template<class Type>
class Array2D{
private:
int lines, columns;
Type **a;
void deallocate() {
if (lines){
for (int i = 0; i < lines; i++){
delete[] a[i];
}
delete[] a;
a = NULL;
}
lines = 0;
columns = 0;
}
void clone(const Array2D<Type>& array2D) {
lines = array2D.lines;
columns = array2D.columns;
a = new Type*[lines];
for (int i = 0; i < lines; i++){
a[i] = new Type[columns];
for (int j = 0; j < columns; j++){
a[i][j] = array2D.a[i][j];
}
}
}
public:
class iterator{
Array2D<Type>& a;
int index;
iterator(int index, Array2D<Type>& a) : index(index), a(a) { }
public:
inline Type& operator* () {
return a[index/a.columns][index%a.columns];
}
inline iterator& operator++ () {
index++;
return (*this);
}
inline bool operator == (const iterator& right) const {
return index == right.index;
}
inline bool operator != (const iterator& right) const {
return index != right.index;
}
friend class Array2D<Type>;
};
inline iterator begin(){
return iterator(0, *this);
}
inline iterator end(){
return iterator(lines*columns, *this);
}
Array2D<Type>() : lines(0), columns(0), a(NULL) { }
Array2D<Type>(int lines, int columns) : lines(lines), columns(columns) {
a = new Type*[lines];
for (int i = 0; i < lines; ++i){
a[i] = new Type[columns];
}
}
Array2D<Type>(const Array2D<Type>& rightValue) {
clone(rightValue);
}
virtual ~Array2D<Type>(){
deallocate();
}
inline Type* operator[] (int line){
return a[line];
}
Array2D<Type>& operator= (const Array2D<Type>& rightValue){
deallocate();
clone(rightValue);
return (*this);
}
template<class T> friend std::ostream& operator<< (std::ostream&, Array2D<T>&);
};
template<class Type>
std::ostream& operator<< (std::ostream& out, Array2D<Type>& array2D){
out << "{";
for (int i = 0; i < array2D.lines; ++i){
out << (i ? "," : "") << "{";
for (int j = 0; j < array2D.columns; ++j){
out << (j ? "," : "") << array2D.a[i][j];
}
out << "}";
}
return out << "}";
}
int main()
{
// Creez o matrice de intr-uri 2x2
Array2D<int> a(2,2);
// Creez si atribui o matrice de int-uri 2x2 (de fapt, aici se cloneaza prin apelul copy-constructorului)
Array2D<int> b = a;
// Parcurg o matrice de int-uri folosind un iterator. Observatie: nu trebuie sa stiu dinainte de dimensiuni are!
for (Array2D<int>::iterator it = a.begin(); it != a.end(); ++it){
(*it) = 6;
}
// Afisez o matrice de int-uri, fara sa trebuiasca sa stiu dinainte ce format intern are!
std::cout << a << " == " << (b = a) << " ?\n";
return 0;
}