Ho aggiunto un po' di funzioni alla mia clesse. In particolare non sono molto convinto della funzione copy (che verrà poi chiamata da operator= e dal costruttore di copia) e della funzione cancel (chiamata dal dostruttore e nella funzione copy). Potreste darmi qualche dritta per migliorare la classe? Grazie!

codice:
#ifndef MATRIX_H
#define MATRIX_H

#include <iostream>
#include <stdexcept>

template <typename T = double>
class Matrix
{
public:
	Matrix(size_t, size_t);
	virtual ~Matrix();
	
	void set(const T&);
	size_t get_row() const;
	size_t get_col() const;
	void print(std::ostream&) const;
	
	T& operator()(size_t, size_t);
	const T& operator()(size_t, size_t) const;

private:
	T** data;
	size_t row;
	size_t col;
	
	void copy(const Matrix<T>&);
	void cancel();
};

#endif

template <typename T>
Matrix<T>::Matrix(size_t r, size_t c)
: row(r), col(c), data(new T*[r])
{
	for(int i(0); i < row; i++)
	{
		data[i] = new T[col];
	}
}

template <typename T>
Matrix<T>::~Matrix()
{
	cancel();
}

template <typename T>
void Matrix<T>::set(const T& d)
{
	for(int i(0); i < row; i++)
	{
		for(int j(0); j < col; j++)
		{
			data[i][j] = d;
		}
	}
}

template <typename T>
size_t Matrix<T>::get_row() const
{
	return row;
}

template <typename T>
size_t Matrix<T>::get_col() const
{
	return col;
}

template <typename T>
void Matrix<T>::print(std::ostream& out) const
{
	for(int i(0); i < row; i++)
	{
		for(int j(0); j < col; j++)
		{
			out << data[i][j] << ' ';
		}
		
		out << std::endl;
	}
}

template <typename T>
T& Matrix<T>::operator()(size_t i, size_t j)
{
	if( (i == 0) or (j == 0) or (i > row) or (j > col))
	{
		throw std::out_of_range("");
	}
	
	return data[i-1][j-1];
}

template <typename T>
const T& Matrix<T>::operator()(size_t i, size_t j) const
{
	if( (i == 0) or (j == 0) or (i > row) or (j > col))
	{
		throw std::out_of_range("");
	}
	
	return data[i-1][j-1];
}

template <typename T>
void Matrix<T>::copy(const Matrix<T>& m)
{
	row = m.row;
	col = m.col;
	
	cancel();
	
	data = new T*[row];
	for(int i(0); i < row; i++)
	{
		data[i] = new T[col];
	}
	
	for(int i(0); i < row; i++)
	{
		for(int j(0); j < col; j++)
		{
			data[i][j] = m.data[i][j];
		}
	}
}

template <typename T>
void Matrix<T>::cancel()
{
	for(int i(0); i < row; i++)
	{
		delete data[i];
	}
	
	delete data;
}

template <typename T>
std::ostream& operator<<(std::ostream& out, const Matrix<T>& m)
{
	m.print(out);
	
	return out;
}