Help debugging code

The code below is supposed to be a program that allows the user to enter in 2 matrices and add them together, and gives an error when they're not the same dimensions.

This is an example from my computer science class that my teacher gave my class. I know this sight says they don't do our homework for us, but this is not a homework assignment, it is just an example from my class that has an error that i, nor the teacher know how to fix. Im currently using Xcode to wire and compile my code which I'm assuming it uses apples version of C++ and is causing the error I'm getting.

the error I'm getting is on line 9 of MAIN.CPP and is saying "The Variable has incomplete type 'Matrix'".

MAIN.CPP
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
  #include <iostream>
#include <vector>
#include <string>
#include "Matrix Class Input.h"
using namespace std;

int main()
{
    class Matrix A,B,C; //Error: Variable has incomplete type 'class Matrix'
    int r,c=0;
    do{
        r=ReadPositiveDouble("Rows in A?");
        c=ReadPositiveDouble("Colums in A?");
    }while(A.Init(r,c,true)==false);
    do{
        r=ReadPositiveDouble("Rows in B?");
        c=ReadPositiveDouble("Colums in B?");
    }while(B.Init(r,c,true)==false);
    A.Display();
    B.Display();
    if(AddMatrix (A,B,C)==true){
        C.Display();
    }
    return 0;
}


MATRIX CLASS INPUT.CPP
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "Matrix Class Input.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Matrix
{
private:
    bool IsValid(unsigned r, unsigned c);
    vector< vector<double> > Values;
public:
    bool Init(unsigned r, unsigned c, bool fill);
    bool SetValue(unsigned r, unsigned c, double v);
    double GetValue(unsigned r, unsigned c);
    void Display();
    void Clear();
    Matrix();
    Matrix(unsigned r, unsigned c, bool fill);
    int Rows();
    int Cols();
};

bool Matrix::Init(unsigned r, unsigned c, bool fill)
{
    bool rv=false;
    if(Rows()>0&&Cols()>0&&Rows()<=100&&Cols()<=100){
        rv=true;
        vector<double> List;
        for(int i=0;i<c;i++){
            List.push_back(0.0);}
        for(int i=0;i<r;i++){
            Values.push_back(List);}
        List.clear();
        if(fill==true){
            for(int i=0;i<r;i++){
                for(c=0;Cols()<c;c++){
                    Values[Rows()][Cols()]=rand();
                }
            }
        }
    }
    return rv;
}

void Matrix::Clear()
{Values.clear();}

Matrix::Matrix()
{ ; }

Matrix::Matrix(unsigned r, unsigned c, bool fill)
{if(Init(r,c,fill)==false)
    cerr<<"Cant Create Matrix\n";}

int Matrix::Rows()
{return Values.size();}

int Matrix::Cols()
{return (Rows()==0)?0:Values[0].size();}

void Matrix::Display()
{
    for(int r=0; r<Rows();r++){
        for(int c=0;c<Cols();c++){
            cout<<Values[r][c]<<'\t';
        }
        cout<<endl;
    }
}

bool Matrix::IsValid(unsigned r, unsigned c)
{
    bool rv=true;
    if(r<0||c<0||r>=Rows()||c>=Cols()){
        cerr<<"Position Outside of Matrix\n";
        rv=false;
    }
    return rv;
}

double Matrix::GetValue(unsigned r, unsigned c)
{return (IsValid(r,c)==true)?Values[r][c]:0.0;}

bool Matrix::SetValue(unsigned r, unsigned c, double v)
{
    bool rv=false;
    if(IsValid(r,c)==true){
        Values[r][c]=v;
        rv=true;
    }
    return rv;
}

double ReadDouble(string Prompt)
{
    bool done=false;
    double rv=0.0;
    do{
        cout<<Prompt;
        cin>>rv;
        if(cin.fail()==0){
            done=true;
        }
        else{
            cin.clear();
            cin.ignore(256,'n');
            cerr<<"Error Could Not Read Data";
        }
    }while(done==false);
    return rv;
}

double ReadPositiveDouble(string Prompt)
{
    double rv=0.0;
    do{
        rv=ReadDouble(Prompt);
        if(rv<=0.0){
            cerr<<"Error RV > 0.0\n";
        }
    }while(rv<0.0);
    return rv;
}


bool AddMatrix(class Matrix& A, class Matrix& B, class Matrix& C)
{
    bool rv=true;
    if(A.Rows()==B.Rows()&&A.Cols()==B.Cols()){
        C.Clear();
        C.Init(A.Rows(),A.Cols(),false);{
            for(int r=0;r<C.Rows();r++){
                for(int d=0;d<C.Cols();d++){
                    C.SetValue(r,d,A.GetValue(r,d)+B.GetValue(r,d));
                }
            }
        }
    }
    else{
        cerr<<"Cant Add Matrices\n";
        rv=false;
    }
    return rv;
}


MATRIX CLASS INPUT.H
1
2
3
4
5
6
7
#include <iostream>
#include <string>
using namespace std;

double ReadDouble(string Prompt);
double ReadPositiveDouble(string Prompt);
bool AddMatrix(class Matrix& A, class Matrix& B, class Matrix& C);


but when i just put all the code on one file it compiles and runs but it only asks for the rows for Matrix A and columns for Matrix A and loops on forever and doesn't get to matrix B
Last edited on
Hi,

Did your teacher give you all the code that you have shown here? Maybe just the class declaration? Or did you write some of it yourself? I am guessing the latter two :+) , because there are a number of problems.

Just a few things to help you out:

- Line 9 is a forward declaration of a class, it is not creating 3 instances of a class. Try :

9
10
11
Matrix A; // note: a good Idea to declare 1 object per line
Matrix B;
Matrix C;


- There is confusion over the naming of your files and where you have class declarations and function definitions.
- A class declaration goes in a header file named the same as the class name - Matrix.hpp
- The class function definitions go into a cpp file named the same as the class name - Matrix.cpp

- You have functions in the MATRIX CLASS INPUT.H file - perhaps the declarations of these could go into their own class, and create a cpp file for their definitions. This is better than lumping different things into one file.

- Your constructor with no arguments, doesn't do anything - so don't provide one. The compiler will implicitly create one if necessary. So this will mean you have one constructor calling the Init function, so you may as well put the code for the Init function into the constructor.

- There is no validation of the arguments r and c for the constructor ( hence Init function) - what if they were negative? Consider making their type std::size_t

- The calls to Rows and Cols on line 27 ultimately return the size of the default creation size of a vector (usually small and guaranteed to be positive) - so the test on line 27 isn't of any use.

- Consider using an initialisation list in the constructor. Google that.

- Don't have using namespace std; Google that as well.

- With error messages say why there is an error.

- With booleans there is no need to explicitly test for false, just use the ! operator:

}while(!done);

- IMHO the functions ReadDouble and ReadPositiveDouble could be integrated into 1 function.

Hope this all helps , look forward to seeing your new code.




> Line 9 is a forward declaration of a class, it is not creating 3 instances of a class
wrong. It does defines three objects.
It comes from C, where you need to do struct foo asdf; to create it.


> a header file named the same as the class name
that's just a (good) convention, file names are not important.


> A class declaration goes in a header file
that would solve the error that you are getting.
main.cpp knows nothing about a `Matrix' class.


> Your constructor with no arguments, doesn't do anything - so don't provide one.
It does do something. It initializes all the member variables using their default constructor. That means that the `Value' vector would be empty.

> The compiler will implicitly create one if necessary
No if you provide another constructor definition.

So given that you have a Matrix(unsigned r, unsigned c, bool fill); constructor, if you want a default one too you need to define it.
If you just want the default behaviour, you may do Matrix() = default; in the declaration.


> The calls to Rows and Cols on line 27 ultimately return the size of the default creation size of a vector
> (usually small and guaranteed to be positive) - so the test on line 27 isn't of any use.
The default constructor of a vector makes it empty, i.e., its size is 0. Meaning that the test on line 27 will always fail.

However, you may call the Init() function on your own, so the test Rows()<=100 is not useless.


> With error messages say why there is an error.
¿what are you trying to say? The OP has posted the error message, which he doesn't understand.


By the way
36
37
38
39
40
            for(int i=0;i<r;i++){
                for(c=0;Cols()<c;c++){
                    Values[Rows()][Cols()]=rand();
                }
            }
¿what do you think you are doing?
this is all the code that my teacher gave me. but the function AddMatrix prototype was originally
bool AddMatrix(Matrix& A, Matrix& B, Matrix& C)

but my teacher decided to add the class to each as a troubleshoot. he wasn't entirely sure what was wrong.

looking back at my original post i mistakingly said the error was on line 11, i meant to say it is on line 9 which is the commented part of the line.

if you try and compile it, does it work for you or are you getting the error as well? its just bothering me that its not working.
Last edited on
ne555 wrote:
¿what are you trying to say? The OP has posted the error message, which he doesn't understand.


I meant on line 141, the code produces an error message "Cant Add Matrices\n". I am suggesting to provide more information as to why the matrices can't be added. Sorry my comment was a little brief - that caused the confusion.

Thanks though, I have learnt some things - I appreciate that :+)

rsalzman94 wrote:
if you try and compile it, does it work for you or are you getting the error as well? its just bothering me that its not working.


This part from ne555:

ne555 wrote:
> A class declaration goes in a header file
that would solve the error that you are getting.
main.cpp knows nothing about a `Matrix' class.
Topic archived. No new replies allowed.