Class function prototypes vs definitions

Sep 19, 2018 at 2:40pm
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()
{

}


Sep 19, 2018 at 2:53pm
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;
}
Sep 19, 2018 at 3:34pm
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.
Sep 19, 2018 at 3:48pm
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
}

Sep 19, 2018 at 4:19pm
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.
Sep 19, 2018 at 4:20pm
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 Sep 19, 2018 at 4:23pm
Sep 19, 2018 at 4:41pm
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.