Ole1991
Ole1991

Reputation: 73

Class inheritance, copy constructor and set/get functions

I got the following class:

class Matrix{
    private:
        int rows;
        int columns;
        double* matrix;
    public:
        Matrix();
        explicit Matrix(int N);
        Matrix(int M, int N);
        void setValue(int M, int N, double value);
        double getValue(int M, int N);
        bool isValid() const;
        int getRows();
        int getColumns();
        ~Matrix();
        friend ostream& operator<<(ostream &out, Matrix&matrix1);

        Matrix &operator=(const Matrix &m) {
            if (rows * columns != m.rows * m.columns){
                delete [] this->matrix;
                this->matrix = new double[m.rows * m.columns];
            }
            rows = m.rows;
            columns = m.columns;
            for(int i = 0; i < rows; i++){
                for(int j = 0; j < columns; j++){
                    this->matrix[i * columns + j] = m.matrix[i * columns + j];
                }
            }
            return *this;
        }
        Matrix(const Matrix &rhs);
};

with these functions

#include <iostream>
#include "Matrix.h"
using namespace std;

//OPPGAVE 2
Matrix::Matrix(){
    matrix = NULL;
}

Matrix::Matrix(int N){
    matrix = new double[N * N];
    rows = N;
    columns = N;

    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            if(i==j)
                matrix[i * N + j] = 1;
            else
                matrix[i * N + j] = 0;
        }
    }
}

Matrix::Matrix(int M, int N){
    matrix = new double[M * N];
    rows = M;
    columns = N;

    for(int i = 0; i < M; i++){
        for(int j = 0; j < N; j++)
            matrix[i * N + j] =  0;
    }
}

Matrix::~Matrix(){
    delete [] matrix;
}

void Matrix::setValue(int M, int N, double value){
    matrix[M * columns + N] = value;
}

double Matrix::getValue(int M, int N){
    return matrix[M * columns + N];
}

bool Matrix::isValid() const{
    if(matrix==NULL)
        return false;
    else
        return true;
}

int Matrix::getRows(){
    return rows;
}

int Matrix::getColumns(){
    return columns;
}

ostream& operator<<(ostream &out, Matrix&matrix1){
    if(matrix1.isValid())
        for(int i = 0; i < matrix1.getRows(); i++){
            for(int j = 0; j < matrix1.getColumns(); j++)
                out << matrix1.getValue(i,j) << "\t";
            out << endl;
        }
    else
        out << "Matrisen er ikke gyldig." << endl;
    return out;
}

Matrix::Matrix(const Matrix &rhs) : rows(rhs.rows), 
    columns(rhs.columns), 
    matrix(new double[rows * columns]) {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                this->matrix[i * columns + j] = rhs.matrix[i * columns + j];
            }
        }
    }

The exercise says:

a) Create a class Vector that inherits the MxN Matrix. We want to use the Vector class as an interface to an Mx1 dimensional matrix with some extra functionality.

b) Implement the following constructors for the Vector class.

Vector()
Default constructor, should initialize the underlying matrix into the invalid state.

explicit Vector(unsigned int N)
Should construct the underlying Mx1 Matrix, initialized as a zero-matrix. (The explicit keyword is not in the syllabus, but it should be used here.)

Vector(const Matrix & other);
Copy-constructor from Matrix. Should assign a matrix to *this if and only if the matrix has dimensions Nx1, otherwise the resulting *this should be set to invalid. Hint: Reuse operator= from the Matrix-class.

This is what I've got so far:

#include "Matrix.h"

class Vector : public Matrix{
    public:
        Vector();
        explicit Vector(int N);
        Vector(const Matrix & other);

};

and

using namespace std;
#include <iostream>
#include "Vector.h"

Vector::Vector() 
    :Matrix(){ }

Vector::Vector(int N)
    :Matrix(N,1){ }

How am I supposed to reuse the operator= from Matrix? If I try to copy it from the Matrix class into the Vector class, it says that rows, columns etc is inaccessible. How do I access these?

Is it possible to write a copy constructor for the Vector class more or less the same as the copy constructor for the Matrix class? They are both arrays, so I guess it should work?

Will the operators I overloaded for Matrix (not included here) automaticly be used if I multiply a Matrix with a Vector, or do I also need to include these somehow in the Vector class? (They were written outside the Matrix class in the Matrix.cpp-file.)

Next Im going to write set and get functions for the Vector class. Is it possible to write these functions on this form?:

void Vector::setValue(int i, double value) {
    Matrix::setValue(i, 1, value);
}

Help and tips are greatly appreciated!

Upvotes: 0

Views: 1452

Answers (2)

Rodney Schuler
Rodney Schuler

Reputation: 2148

You are on the right track for the sets and gets. You can call operators with member function like syntax Class::operator*(args). Implementing the vector assignment would look something like this:

Vector & Vector::operator=(const Vector &v){
    Matrix::operator=(v);
    return *this;
}

You will want your Vector constructors to be declared public. I am thinking because you are using inheritance the compiler will generate correct copy constructors and assignment operators for the Vector class. You should write tests to verify this assumption.

Upvotes: 1

Beta
Beta

Reputation: 99094

What follows is hideous kludgery to satisfy an incompetent professor. Don't do this in the real world.

First, the misnamed "copy" constructor. If we weren't worried about the dimensions, we could do this (shudder):

Vector(const Matrix & other)
{
  *this = other;
}

But we must check the dimensions first. We could do it this way:

Vector(const Matrix & other)
{
  if(other.getColumns()==1)
      *this = other;
}

But some chucklehead neglected to make getColumns() const, so this results in a compiler error. We could do something truly drastic, const cast:

Vector(const Matrix & other)
{
  Matrix *p = const_cast<Matrix *>(&other);
  if(p->getColumns()==1)
      *this = other;
}

Or just something facepalmingly awful:

Vector(const Matrix & other)
{
  Matrix M(other); // notice that this is not const
  if(M.getColumns()==1)
      *this = other;
}

Do you need help with the isValid stuff?

Upvotes: 1

Related Questions