Class function prototypes vs definitions

I have a class that I'm writing that is split into its own .h and .cpp files.
In the .h file I've listed some function prototypes (declarations) listed below.
In the .cpp I have the definitions (so far) written as shown below.
However, if I try to build I get errors where it looks like the compiler thinks the return types for all my functions are int but they're declared as voids. My question is, do I have to state return types in the definitions as well as the declarations? That seems unnecessarily redundant to me. Is there something else I'm doing wrong?

Wing.h
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
#ifndef WING_H
#define WING_H

class Wing
{
    public:
        //Functions
        Wing();
        ~Wing();
        Wing(const Wing& other);
        void SetUnknown( SolveFor );
        
        enum class SolveFor { C, T, W, L };

        //Vars
    protected:

    private:
        //Vars
        SolveFor unknown;
        double wC;
        double wT;
        double wW;
        double wL;

        //Functions
        void SetVars();
        void CheckVars();
        void CalcUnknown();
};

#endif // WING_H 


Wing.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
#include "Wing.h"
#include <iostream>
#include <string>

using namespace std;

Wing::Wing()
{
    //ctor
}

Wing::~Wing()
{
    //dtor
}

Wing::Wing(const Wing& other)
{
    //copy ctor
}

Wing::SetUnknown( d_unknown )
{
    Wing::unknown = d_unknown;
}

Wing::CalcUnknown()
{
    switch ( Wing::unknown ){
    case SolveFor::C:
        if( Wing::wT==0 )
        {
            cout << "Cannot calculate C, T = 0" << endl;
        }
        else
        {
            Wing::wC =  Wing::wL * Wing::wW / Wing::wT;
            cout << "C = " << Wing::wC << endl;
        }
        break;
    case SolveFor::L:
        if( Wing::wW==0 )
        {
            cout << "Cannot calculate length, width = 0" << endl;
        }
        else
        {
            Wing::wL = Wing::wC * Wing::wT / Wing::wW;
            cout << "L = " << Wing::wL << endl;
        }
        break;
    case SolveFor::W:
        if( Wing::wL==0 )
        {
            cout << "Cannot calculate width, length = 0" << endl;
        }
        else
        {
            Wing::wW = Wing::wC * Wing::wT / Wing::wL;
            cout << "W = " << Wing::wW << endl;
        }
        break;
    case SolveFor::T:
        if( Wing::wC==0 )
        {
            cout << "Cannot calculate thickness, C = 0" << endl;
        }
        else
        {
            Wing::wT = Wing::wL * Wing::wW / Wing::wC;
            cout << "T = " << Wing::wT << endl;
        }
        break;
    default:
        cout << "Invalid SolveFor variable" << endl;
        break;
    }
    return void();
}

Wing::CheckVars()
{

}

Wing::SetVars()
{

}


You need to specify the return type in the implementation as well.
1
2
3
4
void Wing::SetUnknown( d_unknown )
{
    Wing::unknown = d_unknown;
}
Thanks for the quick reply! It's a little confusing to me that you don't have to state the parameter variable types again but you have to state the return type again.
you don't have to state the parameter variable types again

That is not true.

A declaration has to have types (but names are optional):
T foo( U );

The definition has to have them too. (If you don't set names, you cannot use the value.)
1
2
3
4
T foo( U bar )
{
  // use bar
}

Ah, that cleared up some other errors I was getting. Thanks again. Sorry, I had it in my head that once you prototyped with the variable types, you didn't have to state the types again.
you typically have to be explicit. This is partly because you can overload things, and partly because c++ is an explicit language.

I just copy my function headers and put a ; on them for the proto. It isnt necessary, but its easy enough.

does adding void in front and putting the type in, eg
void Wing::SetUnknown( *type* d_unknown ) {body}
clear your error?

remember that while it makes no sense here, it is mechanically ok to do this:
void Wing::SetUnknown( vector<double> d_unknown ) {body} //overloaded your method to take a completely different type, it would need a new proto as well, but see how the compiler can't assume too much?
Last edited on
Yes, it cleared out the remaining errors.
Thanks for your explanation. Yeah I can see how you'd need to state the types again for the possibility that you'd be overloading functions. Otherwise it wouldn't know which function definition went with which prototype.

I really appreciate the help guys.
Topic archived. No new replies allowed.