default constructor does not exist in the class

anybody can help with this piece of code;
I am using class to build matrices nut when I define my object it says the default constructor does not exist. how can I fix it?
Thanks in advance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>;
#include <string>;
#include<cstdlib>;
using namespace std;
class Matrix {
public:
	Matrix(int rows, int cols);
	~Matrix();
private:
	const int ROWS;
	const int COLS;
	double *vals;
};

Matrix::Matrix(int rows, int cols) :
	ROWS(rows), COLS(cols)
{
	vals = new double[ROWS * COLS];
}
Matrix::~Matrix()
{
	delete[] vals;
}

int main()
{

	Matrix m1;
	return 0;
}
Last edited on
Well a default constructor has no parameters, so
1
2
3
4
Matrix::Matrix() :
	ROWS(0), COLS(0), vals(nullptr)
{
}
when I define my object it says the default constructor does not exist. how can I fix it?


Either:
(1) write a default constructor (one with no arguments);
or
(2) match your statement in main() to the constructor that you have supplied (takes two ints as parameters);
or
(3) give the parameters in the current constructor some default values (e.g. Matrix::Matrix(int rows=1, int cols=1)
You either need to construct your matrix with the correct number of parameters, and you really should declare the no argument constructor (the "default" constructor) as deleted.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>

using namespace std;

class Matrix {
public:
        Matrix() = delete;
	Matrix(int rows, int cols);
	~Matrix();
private:
	const int ROWS;
	const int COLS;
	double *vals;
};

Matrix::Matrix(int rows, int cols) :
	ROWS(rows), COLS(cols)
{
	vals = new double[ROWS * COLS];
}
Matrix::~Matrix()
{
	delete[] vals;
}

int main()
{

	Matrix m1(10,23);
	return 0;
}

Thank you all for your answers.
how can i set the value for m1?sorry for my naïve question
Last edited on
Do you mean, how do you set the values of the individual array elements?
Either make vals public and access vals[i], or, you could do something like overload the () operator and let it have (row, column) input arguments.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <string>

class Matrix {
public:
    Matrix() = delete;
	Matrix(int rows, int cols);
	~Matrix();
	
	double& operator()(int row, int col)
	{
	    return vals[COLS * row + col];   
	}
	
	const double& operator()(int row, int col) const 
	{
	    return vals[COLS * row + col];   
	}

	const int ROWS;
	const int COLS;
	
private:
	double *vals;
};

Matrix::Matrix(int rows, int cols) :
	ROWS(rows), COLS(cols)
{
	vals = new double[ROWS * COLS];
}
Matrix::~Matrix()
{
	delete[] vals;
}

int main()
{
	Matrix m1(10,23);
	
	m1(0, 0) = 42;
	m1(5, 11) = -100;
	m1(9, 22) = 1700;
	
	for (int i = 0; i < m1.ROWS; i++)
	{
	    for (int j = 0; j < m1.COLS; j++)
	    {
	        std::cout << m1(i, j) << ' ';   
	    }
	    std::cout << '\n';
	}
	
	return 0;
}
Yes,exactly, thanks
As you're not allowing the size to be changed, then the size can only be specified in the constructor. Hence a default constructor is only really valid if it defines a default sized matrix. Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

class Matrix {
public:
	Matrix(size_t rows = defRow, size_t cols = defCol) : ROWS(rows), COLS(cols), vals(new double[rows * cols] {}) {}
	~Matrix() { delete[] vals; }

	double& operator()(size_t row, size_t col) { return vals[COLS * row + col]; }
	const double& operator()(size_t row, size_t col) const { return vals[COLS * row + col]; }

	const size_t ROWS {};
	const size_t COLS {};

	friend std::ostream& operator<<(std::ostream& os, const Matrix& m) {
		for (size_t i = 0; i < m.ROWS; ++i) {
			for (size_t j = 0; j < m.COLS; ++j)
				os << m(i, j) << ' ';

			os << '\n';
		}

		return os;
	}

private:
	static constexpr size_t defRow {10};
	static constexpr size_t defCol {10};

	double* vals {};
};

int main()
{
	Matrix m1(10, 23);
	Matrix m2;

	m1(0, 0) = 42;
	m1(5, 11) = -100;
	m1(9, 22) = 1700;

	m2(2, 2) = 2;
	m2(4, 4) = 44;

	std::cout << m1 << '\n' << m2 << '\n';
}

Last edited on
Actually I want to use this class to produce the local and global stifness matrix in finite element method and the size should be chargeable. And also I want to pass another argument in the class which is the area of each element. The area of each element is obtained by a struct. Since I'm very new in objective oriented programming this gonna be hard for me at this time. I don't know hot to pass an argument within a class which is coming from another class or struct.
@Ganado
I don't understand what these piece of code is doing?
double& operator()(int row, int col)
{
return vals[COLS * row + col];
}

const double& operator()(int row, int col) const
{
return vals[COLS * row + col];
}
Ganado wrote:
overload the () operator

There are two overloads of that operator.

The first returns a reference to element in the matrix:
1
2
3
4
double& operator()(int row, int col)
{
  return vals[COLS * row + col];
}

You can both read and write with it:
1
2
3
Matrix m1(10, 23);
m1( 1, 2 ) = 42; // write
std::cout << m1( 1, 2 ); // read 


However, if the matrix is const, the that operator cannot be used.
The other can be called on const objects:
1
2
3
4
const double& operator()(int row, int col) const
{
  return vals[COLS * row + col];
}

Note that although it too returns a reference, the reference is const. Therefore, one can read elements but not modify them.
Admittedly the const version is a bit silly without a way to initialize non-zero array values in a constructor.
Topic archived. No new replies allowed.