operator [][] matrix c++ - c++

Im trying to create an operator that gives me the value for the position i,j of a certain matrix and another one that "fills" the matrix in the given positions, ive tried to put the operator that you can see in the header but it isnt working, the problem might be somewhere else but i think this it the main issue:
int main()
{
matriz a(3,3);
matrizQuad b(3);
for(size_t i=0;i<3;++i)
for(size_t j=0;j<3;++j){
a[i][j]=1;
b[i][j]=2;
}
matriz c=a+b;
cout << "a+b:\n" << c << "\n";
cout << "traco: " << b.traco() << "\n";
return 0;
} ```
Header:
#ifndef MATRIZES_H
#define MATRIZES_H
#include <iostream>
#include <vector>
#include <ostream>
#include <sstream>
using namespace std;
typedef vector<vector<double>> array;
class matriz
{
protected:
int iLargura, iComprimento;
array m;
public:
matriz(int L, int C): iLargura (L), iComprimento (C)
{
array m(L);
for (int i = 0; i<L;i++)
m[i].resize(C);
};
int nL() const {return iLargura;}
int nC() const {return iComprimento;}
vector<double>& operator[] (int i) {return m[i];}
const vector<double>& operator[] (int i) const {return m[i];}
};
class matrizQuad: public matriz
{
public:
matrizQuad (int T): matriz(T,T) {}
double traco();
};
matriz operator+(const matriz& m1, const matriz& m2);
ostream& operator<<(ostream& output, const matriz& m1);
#endif // MATRIZES_H
Body:
#include "matriz.h"
double matrizQuad::traco()
{
double dSoma = 0;
for (int i = 0;i<iLargura; i++)
for (int j = 0;i<iLargura; i++)
if (i==j)
dSoma = dSoma + m[i][j];
return dSoma;
}
matriz operator+(const matriz& m1, const matriz& m2)
{
int C1 = m1.nC();
int L1 = m1.nL();
matriz m(C1,L1);
for (int i = 0;i<C1; i++)
for (int j = 0;i<L1; i++)
m[i][j] = m1[i][j] + m2[i][j];
return m;
}
ostream& operator<<(ostream& output, const matriz& m1)
{
for(int i = 0; i< m1.nL();i++)
{
for (int j=0;j<m1.nC();j++)
output << m1[i][j] << " ";
output << "\n";
}
return output;
}

Fixing the array resize as 463035818_is_not_a_number suggested gives you a somewhat working matrix.
matriz(int L, int C): iLargura (L), iComprimento (C)
{
m.resize(L);
for (int i = 0; i<L;i++)
m[i].resize(C);
};
If you also print the matrixes a and b you get:
a:
1 1 1
1 1 1
1 1 1
b:
2 2 2
2 2 2
2 2 2
a+b:
3 0 0
3 0 0
3 0 0
So setting and printing matrixes works just fine. The error is in the operator +:
matriz operator+(const matriz& m1, const matriz& m2)
{
int C1 = m1.nC();
int L1 = m1.nL();
matriz m(C1,L1);
for (int i = 0;i<C1; i++)
for (int j = 0;i<L1; i++)
m[i][j] = m1[i][j] + m2[i][j];
return m;
}
specifically:
for (int j = 0;i<L1; i++)
I guess you copy&pasted the previous loop for i and forgot to rename all the variables.

Your class has a member
array m;
This nested vector is never resized. It has size 0.
In the constructor you declare a nested vector of same name
array m(L);
Whose inner vectors you resize in the constructor. Any subsequent access to the members inner vectors elements is out of bounds.
Do not declare another nested vector of same name in the constructor, but instead resize the member.
Note that array is rather misleading for a std::vector<std::vector<double>>. Moreover a nested vector is not an efficient 2d data structure. Anyhow, it is also not clear what your matriz does that you cannot already get from the std::vector<std::vector<double>>.

Related

C++ operator overloading fails to output + operation

I'm learning C++ and trying to write a C++ class for matrices, where I store the matrix as a one-dimensional C array. To this end, I defined an element member function to access the matrix elements based on their location in the array. I have then overloaded the << and + operators to handle the display and addition of matrices. The << operator works as intended, as can be demonstrated in the following example:
#include<iostream>
class matrix {
friend std::ostream & operator<<(std::ostream &os, matrix &M);
private:
int rows{}, columns{};
double *array {nullptr};
public:
matrix(int rows, int columns);
~matrix() {}
double & element(int r, int c);
matrix operator+(matrix &M)
{
matrix N(rows, columns);
if (M.rows!=rows || M.columns!=columns){
std::cout << "ERROR: DIMENSIONS OF MATRICES DO NOT MATCH" << std::endl;
}
else{
for (int i{1}; i<=M.rows; i++)
for (int j{1}; j<=M.columns; j++){
N.element(i,j) = element(i,j) + M.element(i,j);
}
}
return N;
}
};
matrix::matrix(int r, int c)
{
rows = r;
columns = c;
array = new double[rows*columns];
for(int i{0}; i<rows*columns; i++) array[i]=0.0;
}
double & matrix::element(int i, int j)
{
int loc{0};
loc = (j-1) + (i-1)*columns;
return array[loc];
}
std::ostream & operator<<(std::ostream &os, matrix &M)
{
for (int i{1}; i<=M.rows; i++){
os << "[ ";
for (int j{1}; j<=M.columns; j++){
os << M.element(i,j) << " ";
}
os << "] \n";
}
return os;
}
int main() {
matrix A(2,2);
matrix B(2,2);
A.element(1,1) = 1;
A.element(1,2) = 2;
A.element(2,1) = 3;
A.element(2,2) = 4;
B.element(1,1) = 1;
B.element(1,2) = 2;
B.element(2,1) = 3;
B.element(2,2) = 4;
std::cout << A << std::endl;
std::cout << B << std::endl;
return 0;
}
I'm then unable to display the addition of two matrices:
std::cout << A+B << std::endl;
If I, however, break up the operation and add the matrices separately before displaying their sum, I get the right output, which makes me believe that the + operator also works correctly:
matrix C(2,2);
C = A+B;
std::cout << C << std::endl;
The error seems to suggest that there may be an issue converting the matrix elements into the ostream, but it's curious that the above workaround solution works.
Your << operator takes a non-const reference to a matrix as parameter. That means it can't take reference to a temporary object.
The result of A+B is a temporary object if you don't assign it to something.
So you need to change this:
std::ostream & operator<<(std::ostream &os, matrix &M);
into this:
std::ostream & operator<<(std::ostream &os, const matrix &M);
You may sooner or later encounter the same problem with your +-operator:
matrix operator+(matrix &M)
should be
// Both `M` and `*this` should be const
matrix operator+(const matrix &M) const
Naturally you will then have a problem with your element method which can only act on a non-const object, so you also need a variant that acts on a const object:
class matrix
{
....
public:
double & element(int r, int c);
double element(int r, int c) const;
...
}
You can't take a non-const reference of a temporary object. You're trying to call operator<< with a temporary (A+B) but the signature of your overloaded operator<< takes a non-const reference so your function isn't a valid candidate.
To fix this you'll need to change a couple things. First, make your overloaded << operator take a const reference to the matrix. And don't forget to fix the friend signature in the class declaration.
std::ostream & operator<<(std::ostream &os, const matrix &M);
Just doing that will still cause errors because the element method is only defined for non-const objects. You'll need to add an overload for element that acts on const matrixes (and that won't let you modify the returned element).
double matrix::element(int i, int j) const
{
int loc = (j-1) + (i-1)*columns;
return array[loc];
}
Your operator<< and operator+ both need to take the input matrix by const reference, so that they can accept temporary matrix objects as input.
Also, operator+ should be const-qualified since it doesn't modify the contents of this. And element() should have a const -qualified overload so it can provide read-only access to a const matrix object.
You are also missing a copy constructor, a copy-assignment operator, a move constructor, and a move-assignment operator, per the Rule of 3/5/0. And also, your destructor is not freeing the C array at all, so it is being leaked.
Try this instead:
#include <iostream>
#include <stdexcept>
#include <utility>
class matrix {
friend std::ostream& operator<<(std::ostream &os, const matrix &M);
private:
int rows{}, columns{};
double* array{nullptr};
public:
matrix(int rows, int columns);
matrix(const matrix &M);
matrix(matrix &&M);
~matrix();
matrix& operator=(matrix M);
double& element(int r, int c);
double element(int r, int c) const;
matrix operator+(const matrix &M) const;
matrix& operator+=(const matrix &M);
};
matrix::matrix(int r, int c)
: rows(r), columns(c)
{
size_t size = rows*columns;
array = new double[size];
for(size_t i = 0; i < size; ++i)
array[i] = 0.0;
}
matrix::matrix(const matrix &M)
: rows(M.rows), columns(M.columns)
{
size_t size = rows*columns;
array = new double[size];
for(size_t i = 0; i < size; ++i)
array[i] = M.array[i];
}
matrix::matrix(matrix &&M)
: rows(M.rows), columns(M.columns), array(M.array)
{
M.rows = M.columns = 0;
M.array = nullptr;
}
matrix::~matrix()
{
delete[] array;
}
matrix& operator=(matrix M)
{
std::swap(rows, M.rows);
std::swap(columns, M.columns);
std::swap(array, M.array);
return *this;
}
double& matrix::element(int r, int c)
{
// TODO: do bounds checking here...
size_t loc = ((r-1)*columns) + (c-1);
return array[loc];
}
double matrix::element(int r, int c) const
{
// TODO: do bounds checking here...
size_t loc = ((r-1)*columns) + (c-1);
return array[loc];
}
std::ostream & operator<<(std::ostream &os, const matrix &M)
{
for (int r = 1; r <= M.rows; ++r){
os << "[ ";
for (int c = 1; c <= M.columns; ++c){
os << M.element(r,c) << " ";
}
os << "]\n";
}
/* alternatively...
size_t loc = 0;
for (int r = 0; r < M.rows; ++r){
os << "[ ";
for (int c = 0; c < M.columns; ++c){
os << M.array[loc++] << " ";
}
os << "]\n";
}
*/
return os;
}
matrix matrix::operator+(const matrix &M) const
{
matrix N(*this);
N += M;
return N;
}
matrix& matrix::operator+=(const matrix &M)
{
if (M.rows != rows || M.columns != columns){
throw std::runtime_error("DIMENSIONS OF MATRICES DO NOT MATCH");
}
for (int r = 1; r <= rows; ++r)
for (int c = 1; c <= columns; ++c){
element(r,c) += M.element(r,c);
}
}
/* alternatively:
size_t size = rows*columns;
for (size_t i = 0; i < size; ++i)
array[i] += M.array[i];
}
*/
return *this;
}
int main() {
matrix A(2,2);
matrix B(2,2);
A.element(1,1) = 1;
A.element(1,2) = 2;
A.element(2,1) = 3;
A.element(2,2) = 4;
B.element(1,1) = 1;
B.element(1,2) = 2;
B.element(2,1) = 3;
B.element(2,2) = 4;
std::cout << A << std::endl;
std::cout << B << std::endl;
return 0;
}

Overloading << operator to print the elements of a matrix in a template class

why am I having an error on the operator '[]'. I wanted to print the contents of my matrix. If i can't use the brackets, what could i do then?
here's a sample of the code:
#include <iostream>
#include <vector>
template <typename T>
class Matrix {
private:
int m; int n;
std::vector<T> x;
std::vector<std::vector<int>> Mat;
public:
Matrix (const unsigned int &m, const unsigned int &n, std::vector<T> x);
Matrix(const Matrix &M);
Matrix<T> operator = (const Matrix &M);
// Matrix<T> operator [](const int &index);
friend std::ostream& operator << (std::ostream& os, const Matrix<T> &M) {
os << "[";
for (int i = 0; i< M.m; i++){
for (int j = 0; j< M.n; j++){
os << M[i][j] << ' ';
}
os << '\n';
}
os << "]\n";
return os;
}
};
I have fixed the errors. But it doesn't print my matrix.
This is my main:
int main(){
std::vector<int> x = {1,2,3,4};
Matrix<int> A{2,2,x};
Matrix<int> B{2,2,x};
std::cout << A;
std::cout << B;
return 0;
}
And this is my constructor, I needed to make a matrix from a vector where I specify the rows and columns.
template <typename T>
Matrix<T>::Matrix (const unsigned int &m, const unsigned int &n, std::vector<T> x){ //constructor
this -> m = m;
this -> n = n;
this -> x = x;
int index = 0;
for (int i = 0; i<m; i++){
for (int j = 0; j<n; j++){
Mat[i][j] = x[index];
index++;
}
}
}
The issue is this line:
os << M[i][j] << ' ';
Because M is of type Matrix<T> and you haven't defined [] operator, any attempts to use [] operator will give you error.
Instead, You should use data member Mat.
friend std::ostream& operator << (std::ostream& os, const Matrix<T> &M) {
os << "[";
for (int i = 0; i< M.m; i++){
for (int j = 0; j< M.n; j++){
os << M.Mat[i][j] << ' '; // using M.Mat instead of M
}
os << '\n';
}
os << "]\n";
return os;
}
Edit:
As per your updated code, you may get a nice SIGSEGV error (Segmentation Fault) issue. Why? Simple. You are not resizing your data member Mat.
You have to do this:
template <typename T>
Matrix<T>::Matrix (const unsigned int &m, const unsigned int &n, std::vector<T> x){ //constructor
this -> m = m;
this -> n = n;
this -> x = x;
int index = 0;
// resizing Matrix according to our need i.e. m rows and n columns
Mat.resize(m);
for (unsigned int i = 0; i < Mat.size(); i++) {
Mat[i].resize(n);
}
for (unsigned int i = 0; i<m; i++){
for (unsigned int j = 0; j<n; j++){
Mat[i][j] = x[index];
index++;
}
}
}
You have different mistakes in your code:
1.- Your constructor:
Matrix<T>::Matrix (const unsigned int &m, const unsigned int &n, std::vector<T> x)
it's not a good idea to pass a vector by value, its always better to pass it by reference, and never pass an integer by const reference, pass it by value:
Matrix<T>::Matrix (unsigned int m, unsigned int n, const std::vector<T>& x)
2.- This is not an error, but you don't usually need to use "this->", and its better to construct an object like:
Matrix<T>::Matrix (unsigned int m0, unsigned int n0, const std::vector<T>& x0)
: m{m0}, n{n0}, x{x0} {...}
3.- I don't understand why you make 2 copys of the same elements: one in your vector x, and other with M. Your wasting your memory. Maybe with x is enough?
4.- You define m and n as signed int, but in your constructor you use "unsigned" int. Which one do you want to use?
I propose this changes:
1.- If you want to access to an element (i,j), write the operator:
Matrix& operator()(unsigned int i, unsigned int j);
its easy using your vector x.
2.- To write all the elements you can write something like:
std::ostream& operator << (std::ostream& os, const Matrix<T>& M) {
os << "[";
for (int i = 0; i< M.rows(); ++i){
for (int j = 0; j< M.cols(); ++j){
os << M(i, j) << ' ';
}
os << '\n';
}
os << "]\n";
return os;
}
and this is not a friend function (if you define rows() and cols()).
your operator[] returns a Matrix. You should change it to your template value.

Why does operator[] works when initializing and does not work when referring to a 2d dynamic array

I have trouble understanding the problem in the title.
So there are my two classes, a Vector of 3 doubles and a 2D dynamic Matrix that has a Vector object in every cell.
The constructor of Matrix works and does not throw errors. However, when I want to refer to a cell of created Matrix instance in the ostream overload, I'm getting
"no match for 'operator[]' (operand types are 'Matrix' and 'int')"
Why is it OK to use the [][] notation during initialization and not OK later?
Is there a moderately straightforward way to fix this?
Many thanks!
class Vector{
private:
double x, y, z;
public:
Vector(){
x = y = z = 0;
}
Vector(int x_, int y_, int z_){
x = x_;
y = y_;
z = z_;
}
friend ostream &operator<< (ostream &wyj, Vector &v);
friend istream &operator>> (istream &wej, Vector &v);
};
/// ===== MATRIX CLASS CONSISTS OF VECTOR OBJECTS
class Matrix{
private:
Vector ** M;
int row;
int col;
public:
Matrix(int col, int row){
M = new Vector * [row];
for(int i = 0; i < row; i++){
M[i] = new Vector[col];
}
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
M[i][j] = Vector();
}
}
}
friend ostream &operator<< (ostream &wyj, Matrix &M);
};
ostream &operator<< (ostream &wyj, Matrix &M){
for(int i = 0; i < M.row; i++){
for(int j = 0; j < M.col; j++){
wyj << M[i][j] << " ";
}
wyj<< endl;
}
return wyj;
}
int main(){
Matrix A(2, 2);
cout << A[1][1]; // LURD VADAR SAYZ NOOOOOOOOOOOOOOO
}
EDIT: minor typos in << overload method
Why is it OK to use the [][] notation during initialization and not OK
later?
In Matrix's constructor M is a Vector**. In main() A is a Matrix. So [][] is ok for a Vector**, but not meaningful (unless defined) for Matrix.
Is there a moderately straightforward way to fix this?
For [][] to work you need to have operator[] defined twice. Once for the first object and once for the object returned by the first operator[].
So in Matrix you could include:
Vector* operator[](size_t index) { return M[index]; }

The best way to free the memory in static function

This is a Matrix implementation which is working now.
And I need to deallocate the memory of the *data .
But the readMatrix function is static, so I cannot delete [] the data in readMatrix.
What is the best way to do it after the readMatrix returned the *m matrix.
Matrix.cpp
#include "Matrix.h"
#include <sstream>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
Matrix::Matrix(int i, int j) {
rows=i;
cols=j;
data = new float [i * j];
}
Matrix::Matrix(const Matrix& m) {
rows=m.rows;
cols=m.cols;
data=m.data;
}
int Matrix::numRows() {
return rows;
}
int Matrix::numCols() {
return cols;
}
float *Matrix::access(const int i, const int j) const {
return &data[(((i * cols) + j) - 1)] ;
}
std::ostream& operator<<(std::ostream &os, Matrix &m) {
int i, j;
os << m.numRows() << " " << m.numCols() <<endl;
for (i = 0; i < m.numRows(); i++) {
for (j = 0; j < m.numCols(); j++) {
os << *(m.access(i, j)) << " ";
}
os << endl;
}
return os;
}
int **Create2D(int row, int col)
{
int **p = new int* [row];
for (int j = 0; j < row; j ++)
p[j] = new int[col];
return p;
}
// Deletes an array pointed by 'p' that has 'row' number rows
void Delete2D(int **p, int row)
{
for (int j = 0; j < row; j ++)
delete [] p[j];
delete [] p;
}
Matrix Matrix::readMatrix(std::string filename)
{
int r ,c;
ifstream matrixFile(filename.c_str());
matrixFile >> r >> c;
int **p = Create2D(r, c);
Matrix* m = new Matrix(r, c);
for (int i=0; i<r; i++) {
for (int j=0; j<c; j++) {
matrixFile >> p[i][j];
*(m->access(i,j))= (float)p[i][j];
}
}
matrixFile.close();
Delete2D(p, r);
return *m;
}
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <stdlib.h>
#include <iostream>
#include <fstream>
class Matrix {
public:
Matrix(int i, int j) ;
Matrix (const Matrix& m) ;
int numRows ( ) ;
int numCols ( ) ;
float *access(const int i, const int j) const ;
friend std::ostream& operator<<(std::ostream &os, Matrix &m) ;
static Matrix readMatrix ( std::string filename ) ;
private:
Matrix() { }
// ~Matrix() { }
int rows ;
int cols ;
float *data ;
} ;
#endif // MATRIX_H
Thank you!
This here
Matrix::Matrix(const Matrix& m) {
rows=m.rows;
cols=m.cols;
data=m.data;
}
will not work well with your bare float pointer (note that it should be a float**), you end up having more instances pointing to the same data and when they go out of scope they will be deleting the same data more than once causing UB.
What you need to do in a copy constructor is to clone the data. Since you have the rows / cols it should be fairly easy.
now to your question.
This here
...
matrixFile >> p[i][j];
*(m->access(i,j))= (float)p[i][j];
...
(note that you declared access with const at the end (float *access(const int i, const int j) const), this means that the above assignment is illegal, const after the method means the instance will not be affected but you are using it to assign it a value)
seems unnecessary since you are reading one float at a time, it would be enough just to have a single float variable which you use to read the value from the file then assign your matrix that value
...
matrixFile >> floatRead;
*(m->access(i,j))= floatRead;
...
so just ditch the whole p matrix.
Alt. read in the values in the p matrix then let the Matrix instance m take ownership of it.
e.g.
...
m->attachMatrixValues(p);
...

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!
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?
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.