create an array based on size from derived class - c++

So i have an abstract class named Matrice containing a matrix of complex numbers
class Matrice {
Complex** v; //matrix
public:
Matrice() {
v = new Complex * [//lin]; //use size here, without declaring it here
for (int i = 0; i < //lin; i++) {
v[i] = new Complex[//col];
for (int j = 0; j < //col; j++)
cin >> v[i][j];
}
}
virtual void afisare(int lin, int col) {
for (int i = 0; i < lin; i++) {
for (int j = 0; j < col; j++)
cout << v[i][j] << " ";
cout << endl;
}
}
};
and it's derived class
class Matrice_oarecare :Matrice {
int lin, col; //the size i want to use
public:
Matrice_oarecare();
~Matrice_oarecare() {
}
void afisare() { Matrice::afisare(lin, col); }
};
the question is how do i dynamically allocate my matrix using the size specified in my derived class Matrice_oarecare, sorry for the dumb question but i'm new to this inheritance thing

If Matrice_oarecare inherits from Matrice, it has visibility on all protected attributes of Matrice class.
If you want to have access to Complex**v from the derived class then
Complex**v should protected in the base class.
and to allocate in Matrice_oarecare:
v = new Complex*[lin];
for(int i = 0; i < lin; ++i)
v[i] = new Complex[col];
Alternative
You can have a function called allocatein the base class that allocates the Complex** array like so :
class Matrice{
void allocate(int rows, int cols){
v = new Complex*[rows];
for(int i = 0; i < rows; ++i)
v[i] = new Complex[cols];
}
}
and call it from the constructor of the derived class. So you will have
class Matrice_oarecare :Matrice {
int lin, col;
public:
Matrice_oarecare(int rows, int cols):lin(rows),col(cols){
Matrice::allocate(lin, col);
}
~Matrice_oarecare() {
}
void afisare() { Matrice::afisare(lin, col); }
};
also you can have linand col taken as parameters to the contructor of Matrice

Why not just overload the constructor?
You can pass the parameters of the derived constructor to the base_class constructor and than use those parameters as you see fit.
class Matrice {
Complex** v; //matrix
public:
Matrice(int lin, int cols) {
v = new Complex * [lin]; //use size here, without declaring it here
for (int i = 0; i < lin; i++) {
v[i] = new Complex[cols];
for (int j = 0; j < cols; j++)
cin >> v[i][j];
}
}
virtual void afisare(int lin, int col) {
for (int i = 0; i < lin; i++) {
for (int j = 0; j < col; j++)
cout << v[i][j] << " ";
cout << endl;
}
}
};
class Matrice_oarecare :Matrice {
int lin, col; //the size i want to use
public:
Matrice_oarecare():
Matrice(lin, col) {};
~Matrice_oarecare() {}
void afisare() { Matrice::afisare(lin, col); }
};

Related

Passing data from constructor to member function

I am trying to write a class that do matrix multiplication. The
class matrix declared like below:
class matrix
{
public:
vector<vector<int> > M;
matrix();
matrix(int m, int n);
matrix(vector<vector<int> > &m);
matrix Mul(matrix m1);
void Inverse();
bool SquareMatrix();
void GetDet();
int Det(vector<vector<int> > &m);
void Print();
};
I initialize and enter the elements of the matrix M in this constructor:
matrix::matrix(int m, int n)
{
vector<vector<int> > M(m, vector<int>(n, 0));
cout << "Enter the elements: " << endl;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> M[i][j];
}
}
}
However, the member function "Mul" do not receive the data I input through the constructor.
matrix matrix::Mul(matrix m1)
{
int **ppInt;
ppInt = new int *[M.size()];
for (int i = 0; i < M.size(); i++)
{
ppInt[i] = new int[m1.M[0].size()];
}
if (M[0].size() != m1.M.size())
{
cout << "Cannot do multiplication!" << endl;
return matrix();
}
else
{
for (int i = 0; i < M.size(); i++)
{
for (int j = 0; j < m1.M[0].size(); j++)
{
int ele_buf = 0;
for (int k = 0; k < M[0].size(); k++)
{
ele_buf += M[i][k] * m1.M[k][j];
}
ppInt[i][j] = ele_buf;
}
}
}
int d1 = M.size(), d2 = m1.M[0].size();
for (int i = 0; i < M.size(); i++)
{
M[i].clear();
}
M.clear();
for (int i = 0; i < d1; i++)
{
for (int j = 0; j < d2; j++)
{
M[i][j] = ppInt[i][j];
}
}
}
How can I fix it?
Please let me know if my problem is not clear enough.
I initialize and enter the elements of the matrix M in this
constructor!
No! You are working with a local M, not with the member M.
In the constructor
matrix::matrix(int m, int n)
{
vector<vector<int> > M(m, vector<int>(n, 0)); // local to the constructor only!
// .........
}
the M is local to the scope of the constructor, which shadows the member you defined with the same name M. Therefore it (i.e the one in the constructor) will be destroyed after the constructor scope. In effect, the member M will never get initialized.
How can I fix it?
In order to fix, you might want to std::vector::resize the member M
matrix(int m, int n)
{
M.resize(m, vector<int>(n, 0)); // resize M with `m` and `n`
std::cout << "Enter the elements: " << std::endl;
for (std::vector<int>& row : M)
for (int& ele : row)
std::cin >> ele; // fill the elements
}
I initialize and enter the elements of the matrix M in this constructor:
No you don't. You are initializing a vector called M that shadows the member with the same name. The M in the constructor is a different vector that is local to the constructor.
To initialize members, use the initializer list:
matrix::matrix(int m, int n) : M(m, vector<int>(n, 0)) {
cout << "Enter the elements: " << endl;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> M[i][j];
}
}
}

Arbitrary matrix dimension in matrix class

The task is as follows: Describe the class "matrix of numbers" with component data: the dimensions of the matrix, a pointer to the elements. Overload operations: << (matrix output to the screen), + (addition of matrices), unary ¬– (change the sign of each element), / = (divide each element by a number). I performed it, and performed it correctly, but you need to set the matrix dimension from the keyboard, and as you can see, it is set in advance for me [3] [3]. It sounds pretty simple, but something I'm really dumb. Thanks in advance for your help. Here is the code:
#include "pch.h"
#include <iostream>
using namespace std;
class Matrix
{
public:
Matrix()
{
int Table[3][3];
}
int Table[3][3];
void Create()
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
Table[i][j] = 10;
}
};
ostream& operator <<(ostream& t, Matrix a)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
t << a.Table[i][j] << " ";
t << "\n";
}
return t;
}
Matrix& operator /=(Matrix& a, int num)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] /= num;
return a;
}
Matrix& operator -(Matrix& a, int empty)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] = -a.Table[i][j];
return a;
}
Matrix& operator +(Matrix& a, Matrix b)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] += b.Table[i][j];
return a;
}
int main()
{
int u;
setlocale(LC_ALL, "Russian");
Matrix Example;
Example.Create();
Matrix Example1;
Example1.Create();
cout << Example;
cout << Example1;
cout << "Сумма матриц: "<<endl;
cout << Example + Example1;
Example - 1;
Example1 - 1;
cout<< Example + Example1;
cout << "На сколько вы хотите её поделить?\n";
cin >> u;
Example /= u;
Example1 /= u;
cout << Example;
cout << Example1;
}`
You need to dynamically create the matrix.
In order to this you need to use pointers(*). Change int table[3][3]
double table**;
An example of how it could be implemented (note that I use matrix instead of table)
class Matrix {
private:
double** matrix;
int col;
int row;
public:
Matrix(){};
void Create(int row, int col);
};
void Matrix::Create(int row_, int col_){
double val = 0.0;
col = col_; // initalize private members
row = row_;
matrix = new double*[row]; // Create a new array of size row_
for(int i = 0; i < row; i++)
{
matrix[i] = new double[col]; // Create new cols of size col (inside array of row)
}
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
matrix[i][j] = val;
val = val + 1.0;
}
}
}
I tried to reuse your design for simplicity, but I really suggest that you try to specify the dimensions of the matrix in a constructor instead and maybe even construct the matrix in it as well.
Something like this:
Matrix(int row_, int col_) : row(row_), col(col_) {*/ create matrix here /*};
You can skip the "create matrix here" part and use your own Create() if you want to.
You need dynamic memory allocation for that. I won't fiddle around with pointers (new / delete) unless you are explicitly told to. As a beginner you should probably use the standard template library (STL) tools:
#include <vector> and use std::vector<std::vector<int>> Table instead of int Table[3][3]. Then write a constructor like this:
Matrix(std::size_t rows, std::size_t cols)
{
Table.resize(rows);
for (unsigned int i = 0; i < Table.size(); ++i)
Table[i].resize(cols);
}
You can additionally store the dimension of the matrix, but there is no need to do it since you can get the information from the vectors. Replace the hardcoded dimensions in all loops by the corresponding dynamic sizes (stored or extracted from the vectors). For example:
Matrix& operator +(Matrix& a, Matrix b)
{
unsigned int rows = a.Table.size();
unsigned int cols = a.Table[0].size();
for (unsigned int i = 0; i < rows; i++)
for (unsigned int j = 0; j < cols; j++)
a.Table[i][j] += b.Table[i][j];
return a;
}
However, this vector of vectors is not really effective. Better would be a single vector but I guess for a beginner it is okay.
Greetings

C++ gives me an error: no match for call to

I have a problem using static_cast. Here is my program:
#include <iostream>
using namespace std;
class Mtx { // base matrix
private:
// refer to derived class
Mtx& ReferToDerived() {
return static_cast<Mtx&>(*this);
}
// entry() uses features of derived class
virtual double& entry(int i, int j){
return ReferToDerived() (i,j); // error appears here
}
protected:
int dimn; // dimension of matrix
public:
// define common functionality in base class that can
// be called on derived classes
double sum() { // sum all entries
double d = 0;
for (int i = 0; i < dimn; i++)
for (int j = 0; j < dimn; j++) d += entry(i,j);
return d;
}
};
class FullMtx: public Mtx {
double** mx;
public :
FullMtx(int n) {
dimn = n;
mx = new double* [dimn] ;
for (int i=0; i<dimn; i++) mx[i] = new double [dimn];
for (int i=0; i<dimn; i++)
for (int j=0; j<dimn; j++)
mx[i][j] = 0; // initialization
}
double& operator() (int i, int j) { return mx[i] [j]; }
};
class SymmetricMtx : public Mtx {
// store only lower triangular part to save memory
double** mx ;
public :
SymmetricMtx(int n) {
dimn = n;
mx = new double* [dimn];
for (int i=0; i<dimn; i++) mx[i] = new double [i+1];
for (int i=0; i<dimn; i++)
for (int j=0; j <= i; j++)
mx[i][j] = 0; // initialization
}
double& operator() (int i, int j) {
if (i >= j ) return mx[i][j] ;
else return mx[j][i]; // due to symmetry
}
};
int main()
{
FullMtx A(1000);
for (int i=0; i<1000; i++)
for (int j=0; j<1000; j++)
A(i,j)=1;
cout << "sum of full matrix A = " << A.sum() << '\n';
SymmetricMtx S(1000); // just assign lower triangular part
for (int i=0; i<1000; i++)
for (int j=0; j<1000; j++)
S(i,j)=1;
cout << "sum of symmetric matrix S = " << S.sum() << '\n';
}
When I run it, it says: no match for call to '(Mtx) (int&, int&)'
And I don't understand what's wrong and how should I modify it? It should be written using virtual functions, but I don't know how can I write it correctly. Can someone help me?
This program should count the sum of all the elements of the FullMatrix and SymmetricMatrix.
remove virtual here
virtual double& entry(int i, int j){
return (*this)() (i,j); // error appears here
}
add virtual there
class Mtx {
...
virtual double& operator() (int i, int j) = 0;
}
let the derived classes overload that operator and voala.
class FullMtx: public Mtx {
...
virtual double& operator() (int i, int j) override { return mx[i] [j]; }
}
also this is just nonsense as already pointed out. you cast to same type, not the derived one.
besides that you can't cast to derived type because in base you don't have the information about full inheritance - what if somebody derives from FullMtx without your knowledge ?
Mtx& ReferToDerived() {
return static_cast<Mtx&>(*this);
}

Implement 2D matrix from classes C++

I'm new to C++ and currently I'm trying to implement 2D matrix from classes, this is my current code, right now I'm unable to create an instance of the matrix object, please leave me feedback what I need to fix.
*Updated: I have fixed some of the code, but the matrix doesn't print anything
#include <iostream>
#include <cstdlib>
using namespace std;
class Matrix
{
public:
Matrix(); //Default constructor
Matrix(int *row, int *col); //Main constructor
void setVal(int row, int col, int val); //Method to set the val of [i,j]th-entry
void printMatrix(); //Method to display the matrix
~Matrix(); //Destructor
private:
int row, col;
double **matrix;
//allocate the array
void allocArray()
{
matrix = new double *[*row];
for (int count = 0; count < *row; count++)
*(matrix + count) = new double[*col];
}
};
//Default constructor
Matrix::Matrix() : Matrix(0,0) {}
//Main construcor
Matrix::Matrix(int *row, int *col)
{
allocArray();
for (int i=0; i < *row; i++)
{
for (int j=0; j < *col; j++)
{
*(*(matrix + i) + j) = 0;
}
}
}
//destructor
Matrix::~Matrix()
{
for( int i = 0 ; i < row ; i++ )
delete [] *(matrix + i) ;
delete [] matrix;
}
//SetVal function
void Matrix::setVal(int row, int col, int val)
{
matrix[row][col] = val;
}
//printMatrix function
void Matrix::printMatrix()
{
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
cout << *(*(matrix + i) + j) << "\t";
cout << endl;
}
}
int main()
{
int d1 = 2;
int d2 = 2;
//create 4x3 dynamic 2d array
Matrix object(&d1,&d2);
object.printMatrix();
return 0;
}
Your line
Matrix object = new int **Matrix(d1,d2);
is wrong. Use simply
Matrix object(d1,d2);
no need for Java-like syntax which in fact in C++ means dynamic allocation: Matrix* object = new Matrix(d1,d2);
Instead of Matrix object = new int **Matrix(d1,d2); use Matrix* object = new Matrix(d1,d2);
Also, you will have to use object->printMatrix(); instead of object.printMatrix();

Class matrix addition

I have a program that is suppose to add together two matrices but when it gets to the add part in the main it just gets stuck and does nothing. I have messed with this for quite some time but to no avail. Any help or recommendations would be appreciated.
#include <iostream>
using namespace std;
class matrix
{
private:
int **p, m, n;
public:
matrix(int row, int col)
{
m = row;
n = col;
p = new int*[m];
for (int i = 0; i < m; i++)
p[i] = new int[n];
}
~matrix()
{
for (int i = 0; i < m; i++)
delete p[i];
delete p;
}
void fill()
{
cout<<"Enter the matrix elements:";
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
cin >> p[i][j];
}
}
}
void display()
{
cout <<"The matrix is:";
for(int i = 0; i < m; i++)
{
cout << endl;
for(int j = 0; j < n; j++)
{
cout << p[i][j] <<" ";
}
}
cout << endl;
}
matrix operator +(matrix m2)
{
matrix T(m, n);
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
T.p[i][j] = p[i][j] + m2.p[i][j];
}
}
return T;
}
matrix operator =(matrix eq)
{
m = eq.m;
n = eq.n;
p = eq.p;
return *this;
}
friend matrix operator *(matrix, matrix);
};
matrix operator *(matrix a , matrix b)
{
matrix B(1,1);
if(a.n == b.m)
{
matrix T(a.m, b.n);
for(int i = 0; i < a.m; i++)
{
for(int k = 0; k < b.n; k++)
{
T.p[i][k] = 0;
for(int j = 0; j < a.n; j++)
{
T.p[i][k]+= a.p[i][j] * b.p[j][k];
}
}
}
B = T;
}
return B;
}
int main()
{
matrix a(3,3), b(3,3);
a.fill();
a.display();
b.fill();
b.display();
cout << "addition of a and b\n";
b = b + a;
b.display();
cout << "multiplication of a and b\n";
b = (a * b);
b.display();
}
Your program is violating the rule of big three: it has a destructor but no assignment operator and no copy constructor. It keeps the data using raw pointers, but it's not managing proper ownership with copies are done and assignments are performed.
When your matrix class is copied and assigned your program is entering the Undefined Behavior territory so anything can happen. In this code copy construction is done implicitly when passing a matrix parameter by value, and assignment is done explicitly in main.