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

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);
}

Related

Object of a class corrupted when calling a member function of the class

A great deal of unexpected numbers outputted on my console window when I compiled and ran the program.
The class "matrix" is declared as 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();
};
the member function "Mul":
matrix matrix::Mul(matrix m1)
{
vector<vector<int> > Temp(M.size(), vector<int>(m1.M[0].size(), 0));
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];
}
Temp[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();
M.resize(Temp.size(), vector<int>(Temp[0].size(), 0));
for (int i = 0; i < d1; i++)
{
for (int j = 0; j < d2; j++)
{
M[i][j] = Temp[i][j];
}
}
}
M[i][j] hold the expected value at this point.
the member function "Print":
void matrix::Print()
{
for (int i = 0; i < M.size(); i++) {
for (int j = 0; j < M[0].size(); j++) {
cout << M[i][j] << " ";
}
cout << endl;
}
}
Output wrong M.
main:
/*
call constructor to initialize m1 and m2
*/
//...
matrix m3 = m1.Mul(m2);
m3.Print();
//...
How can I fix it?
I'm new here, plz let me know if I didn't make my question clear.
Editted:
matrix matrix::Mul(matrix m1)
{
vector<vector<int> > Temp(M.size(), vector<int>(m1.M[0].size(), 0));
if (M[0].size() != m1.M.size())
{
cout << "Cannot do multiplication!" << endl;
return matrix();
}
else
{
//TO_DO: Multiply two matrixes and print the result.
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];
}
Temp[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();
return matrix(Temp);
}
Functionning properly,
thanks.
You forgot to add a return statement, which is trivial to fix. However, your code is not written in a good OO manner, so here come few suggestions for the improvement:
don't pass matrix m1 by value, because you are paying an expensive copy each time you invoke this function; use const matrix& m1 instead
in the body of Mul you are modifying member M, which is a serious side effect; remove the part of code:
int d1 = M.size(), d2 = m1.M[0].size();
for (int i = 0; i < M.size(); i++)
{
M[i].clear();
}
M.clear();
instead of implementing a separate function called Mul, overload the * operator (see e.g. here and here)
You are promised to return matrix from the Mul function
matrix matrix::Mul(matrix m1);
^^^^^^
and you did not keep the promise. This can cause undefined behaviour to your program.
Add an proper return statement in the function.
matrix matrix::Mul(matrix m1)
{
// ... code
return *this; // matrix(Temp) itself
}

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];
}
}
}

Printing out matrix in c++, class method problem

I want to display a matrix using class and methods. Im getting "C:\Users\PC\AppData\Local\Temp\cc41EMS5.o:lab6.cpp:(.text+0x3d6): undefined reference to `Matrix::Matrix()'
collect2.exe: error: ld returned 1 exit status" error. I guess its because of printMatrix method(that worked not as a method in main), but I dont know how to fix that.
Here is the code:
#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
class Matrix {
public:
Matrix();
Matrix(int rowSize, int colSize);
void setSize(int rowSize, int colSize);
string printMatrix(int rowSize, int colSize);
void free_data();
void allocate_data();
private:
int rowSize;
int colSize;
double **p;
//vector<vector<int>> matrix(rowSize, vector<int>(colSize));
};
void Matrix::allocate_data() {
p = new double *[rowSize];
for (int i = 0; i < rowSize; i++) {
p[i] = new double[colSize];
}
}
void Matrix::free_data() {
for (int i = 0; i < rowSize; i++) {
delete[] p[i];
}
delete[] p;
}
void Matrix::setSize(int rowSize, int colSize) {
int newSize = 0;
p[rowSize][colSize] = newSize;
}
Matrix::Matrix(int rowSize, int colSize) {
this->rowSize = rowSize;
this->colSize = colSize;
allocate_data();
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
p[i][j] = 0;
}
}
}
string Matrix::printMatrix(int rowSize, int colSize) {
int i, j;
int matrix[i][j];
for (int i = 0; i < rowSize; i++) //it worked in main, but doesn't in class
{
for (int j = 0; j < colSize; j++) {
0 >> matrix[i][j];
}
cout << endl;
}
cout << "Matrix" << endl;
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
cout << matrix[i][j] << " ";
}
cout << "\n";
}
cout << endl;
}
int main() {
int rowSize;
int colSize;
cout << "Enter size of rows and columns: ";
cout << "Rows: ";
cin >> rowSize;
cout << "Cols: ";
cin >> colSize;
Matrix m;
m.printMatrix(rowSize, colSize);
return 0;
}
Please send help
You declare two constructors:
Matrix();
Matrix(int rowSize, int colSize);
But you define only one:
Matrix::Matrix(int rowSize, int colSize)
{
this->rowSize=rowSize;
this->colSize=colSize;
allocate_data();
for(int i=0; i<rowSize; i++)
{
for(int j=0; j<colSize; j++)
{
p[i][j]=0;
}
}
}
Furthermore, in `main` you call the constructor that you happened to not define:
> ```
> Matrix m;
> ```
Instead, get rid of the declaration for `Matrix::Matrix()` since you lack a definition, and use the constructor that takes two arguments:
int main()
{
int rowSize;
int colSize;
cout<<"Enter size of rows and columns: ";
cout<<"Rows: ";
cin>>rowSize;
cout<<"Cols: ";
cin>>colSize;
Matrix m(rowSize, colSize);
m.printMatrix(rowSize,colSize);
return 0;
}
## Additional improvements
You don't need to pass the size of the matrix to `Matrix::printMatrix`, since the matrix already has the size as members. By passing those parameters to `printMatrix`, you're making the class more confusing and error-prone to use. If I constructed a 3x3 matrix and tried to call `printMatrix(10,10)` on it, I would certainly invoke undefined behavior and likely crash the program.
Get rid of the parameters (in both definition and declaration) and use the existing `rowSize` and `columnSize` fields to control the loops in that function. The return type also ought to be `void`.
Also, `0 >> matrix[i][j];` makes no sense. The correct syntax is `matrix[i][j] = 0;`.
You define and use a parameterless Matrix constructor (Matrix();) but you do not implement it.
You may either:
Delete the Matrix() definition and use the constructor that you define (Matrix m(rowSize, colSize);)
Implement the parameterless constructor, creating the matrix with some predefined values. You can use a delegating constructor to call the constructor that accepts parameters
Matrix::Matrix() : Matrix(4,4) {
}
I would recommend the first option

create an array based on size from derived class

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); }
};

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.