Matrix-Klasse mit View- und ConstView-Funktionalität

Durch ein weitere Attribut isConst soll intern festgehalten werden, ob Matrix-Elemente verändert werden dürfen. Falls nicht, dann soll der Aufruf einer nicht als const dekalierten Methode oder Operator eine Assertion erzeugen.

Aufgaben

#include <cassert>
#include <cstdio>

struct Matrix
{
    Matrix(long numRows, long numCols);

    Matrix(const Matrix &X, bool takeView=false);

    Matrix(Matrix &X, bool takeView=false);

    ~Matrix()

    void
    operator=(const Matrix &X);

    const double &
    operator()(long i, long j) const;

    double &
    operator()(long i, long j);

    long    numRows, numCols;
    double  *data;
    bool    isView;
    bool    isConst;
};

void
init(Matrix &A, long offset=1)
{
    for (long i=0; i<A.numRows; ++i) {
        for (long j=0; j<A.numCols; ++j) {
            A(i,j) = i+j*A.numRows+offset;
        }
    }
}

void
print(const Matrix &A, const char *name = 0)
{
    std::printf("\n[%s]\n", A.isView ? "view" : "no view");
    if (name) {
        std::printf("%s =\n", name);
    }
    for (long i=0; i<A.numRows; ++i) {
        for (long j=0; j<A.numCols; ++j) {
            std::printf(" %5.1lf", A(i,j));
        }
        std::printf("\n");
    }
    std::printf("\n");
}

void
foo(const Matrix &A)
{
    /* ... */
}

int
main()
{
    Matrix A(4,5);
    init(A);
    print(A, "A\n");
    foo(A);
    print(A, "A\n");
}