Question regarding header and implementation files.

I am a beginner, and I currently am trying to finish a project for a Computer Science class.

I did research the archives and actually found someone asking a similar question. I also researched forums dedicated to CodeBlocks, but I decided to post my question here after I realized that I could not make the suggestions on the resources I found work for me.

My question has to do with making a header, implementation, and test file work properly. No matter what I do, I cannot make the test file properly recognize the implementation file.

As mentioned before I am using CodeBlocks to try and finish this project, and I imagine that it is possible that I am not using it correctly to finalize it. As a result, I am thoroughly lost on this one, since the instructor did not really cover this in class and left it for us to figure it out.

I will provide all the code I wrote for the sake of being thorough, but my question has nothing to do with the program itself. I know it works because I have tested it thoroughly as a single entity in one file, and it does what it should.

I need help only making the header, implementation, and test files work
together.

Header file clockType.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
33
34
35
#include <iostream>
#ifndef clockType_h
#define clockType_h

class clockType
{
public:
    void setTime (int, int, int); //Sets time to a given value.
    void getTime (int&, int&, int&) const;
    void printTime () const; //Prints time.
    void incrementSeconds(); //Increments time by 1 second.
    void incrementMinutes(); //Increments time by 1 minute.
    void incrementHours(); //Increments time by 1 hour.
    bool equalTime (const clockType&) const; //Compares equality
                                             //of two times.
    clockType(int = 0, int = 0, int =0);
    
    //Functions that overload the operators.
    bool operator==(const clockType& otherClock) const;
    bool operator!=(const clockType& otherClock) const;
    bool operator<(const clockType& otherClock) const;
    bool operator>(const clockType& otherClock) const;
    void operator=(const clockType& otherClock);

private:
    int hr;
    int min;
    int sec;
};

int hours;
int minutes;
int seconds;

#endif 


Implementation file clockTypeImp.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
#include<iostream>
#include "clockType.h"
#ifndef clockType_Imp
#define clockType_Imp

using namespace std;

clockType::clockType(int hours, int minutes, int seconds)
{
    setTime(hours, minutes, seconds);
}

void clockType::setTime(int hours, int minutes, int seconds)
{
    if (0 <= hours && hours < 24)
    {
        hr = hours;
    }
        else
            hr = 0;

    if (0 <= minutes && minutes < 60)
    {
        min = minutes;
    }
        else
            min = 0;

    if (0 <= seconds && seconds < 60)
    {
        sec = seconds;
    }
        else
            sec = 0;
}

void clockType::getTime(int&, int&, int&) const
{
    hours = hr;
    minutes = min;
    seconds = sec;
}

void clockType::printTime() const
{
    if (hr < 10)
        cout << "0";
        cout << hr << ":";

    if (min < 10)
        cout << "0";
        cout << min << ":";

    if (sec < 10)
        cout << "0";
        cout << sec;
}

void clockType::incrementHours()
{
    hr++;
    if (hr > 23)
        hr = 0;
}

void clockType::incrementMinutes()
{
    min++;
    if (min > 59)
    {
        min = 0;
        incrementHours();
    }
}

void clockType::incrementSeconds()
{
    sec++;
    if (sec > 59)
    {
        sec = 0;
        incrementMinutes();
    }
}

bool clockType::equalTime(const clockType& otherClock) const
{
    return (hr==otherClock.hr &&
            min==otherClock.min &&
            sec==otherClock.sec);
}

bool clockType::operator==(const clockType& otherClock) const
{
    return (hr==otherClock.hr &&
            min==otherClock.min &&
            sec==otherClock.sec);
}

bool clockType::operator!=(const clockType& otherClock) const
{
    return (hr!=otherClock.hr ||
            min!=otherClock.min ||
            sec!=otherClock.sec);
}

bool clockType::operator<(const clockType& otherClock) const
{
    return (hr<otherClock.hr ||
           (hr==otherClock.hr && min<otherClock.min) ||
           (hr==otherClock.hr && min==otherClock.min &&
           sec<otherClock.sec));
}

bool clockType::operator>(const clockType& otherClock) const
{
    return (hr>otherClock.hr ||
           (hr==otherClock.hr && min>otherClock.min) ||
           (hr==otherClock.hr && min==otherClock.min &&
           sec>otherClock.sec));
}

void clockType::operator=(const clockType& otherClock)
{
    min = otherClock.min;
    hr = otherClock.hr;
    sec = otherClock.sec;
}

#endif 


Test file 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
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
#include<iostream>
#include "clockType.h"

using namespace std;

int main()
{
    clockType oneClock (15);
    clockType twoClock (5, 25);
    clockType yourClock;
    clockType equalClock;
    clockType myClock (12, 30, 30);

    cout << "The default myClock time is: ";
    myClock.getTime(hours, minutes, seconds);
    cout << hours << ":" << minutes << ":" << seconds;
    cout << endl;

    cout << "The default yourClock time is: ";
    yourClock.printTime();
    cout << endl;

    cout << "The default oneClock time with one parameter ";
    cout << "declared is: ";
    oneClock.printTime();
    cout << endl;

    cout << "The default twoClock time with two parameters ";
    cout << "declared is: ";
    twoClock.printTime();
    cout << endl;

    cout << "\nEnter hours, minutes, and ";
    cout << "seconds in the format (h m s): ";
    cin >> hours >> minutes >> seconds;
    cout << endl;
    yourClock.setTime(hours, minutes, seconds); 

    if (myClock.equalTime(yourClock))
    {
        cout << "Time in objects myClock and yourClock is equal ";
        cout << "by using equalTime function.";
    }
    else
        {
        cout << "Time in objects myClock and yourClock is not equal ";
        cout << "by using equalTime function.";
        }

    if (myClock != yourClock)
    {
        cout << "\nTime in objects myClock and yourClock is not equal ";
        cout << "by using != overloaded operator.";
    }
    else
    {
        cout << "\nTime in objects myClock and yourClock is equal ";
        cout << "by using != overloaded operator.";
    }

    if (myClock == yourClock)
    {
        cout << "\nTime in objects myClock and yourClock is equal ";
        cout << "by using == overloaded operator.";
    }
    else
    {
        cout << "\nTime in objects myClock and yourClock is not equal ";
        cout << "by using == overloaded operator.";
    }

    if (myClock > yourClock)
    {
        cout << "\nTime in object myClock is greater than time in object";
        cout << " yourClock by using > overloaded operator.";
    }
    else
    {
        cout << "\nTime in object myClock is not greater than time in";
        cout << " object yourClock by using > overloaded operator.";
    }

    if (myClock < yourClock)
    {
        cout << "\nTime in object myClock is less than time in object";
        cout << " yourClock by using < overloaded operator.";
    }
    else
    {
        cout << "\nTime in object myClock is not less than time in";
        cout << " object yourClock by using < overloaded operator.";
    }

    cout<<"\n\nTime in myClock is: ";
    myClock.printTime();
    cout<<"\nThe user updated yourClock time is: ";
    yourClock.printTime();

    equalClock = yourClock;
    cout << "\nTime in equalClock after using = overloaded operator: ";
    equalClock.printTime();

    equalClock.incrementSeconds();
    cout << "\nTime in equalClock after incrementing seconds: ";
    equalClock.printTime();
    equalClock.incrementMinutes();
    cout << "\nTime in equalClock after incrementing minutes: ";
    equalClock.printTime();
    equalClock.incrementHours();
    cout << "\nTime in equalClock after incrementing hours: ";
    equalClock.printTime();

    cout << endl << endl;
    cout << "Press any key and press enter to terminate the program: ";
    char c;
    cin >> c;
    return 0;
}


Errors I get when debugging/building main.cpp, which, incidentally, creates main.o and clockTypeImp.o:
1
2
3
4
5
6
7
8
9
10
||=== Build: Debug in Test (compiler: GNU GCC Compiler) ===|
obj\Debug\main.o||In function `main':|
|7|multiple definition of `hours'|
|17|first defined here|
|7|multiple definition of `minutes'|
|17|first defined here|
|7|multiple definition of `seconds'|
|17|first defined here|
||error: ld returned 1 exit status|
||=== Build failed: 7 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Don't create variables:
1
2
3
int hours;
int minutes;
int seconds;


in the header file. The header file is included in more than one *.cpp file, so both those *.cpp files are trying to create global values:
1
2
3
int hours;
int minutes;
int seconds;


So you're trying to create the exact same variables, with the exact same names, at global level, more than once. This is bad.

If you need variables to exist, create them in main. That's where you're creating all your other variables.
Last edited on
Looks like a name clash with the local variables with the same name in clockTypeImp.cpp
Remove lines 31-33 in your header file and declare them local in main.
Hello,
How are you compiling (most importantly, linking) the project? Your implementation file's object code (.o) has to be linked with your test file's source (.o) AND you have to include the header file (the header file tells the compiler that such a function or variable exists, and to go look for it's implementation during linking. The implementation file contains the actual implementation). Your test file won't magically be aware of your implementation file unless you provide the file. On g++, you can link two (or more) objects by passing the object files (instead of source) to g++. Object files are generated passing the -c switch to g++.
Hope that helped,
ndrewxie (or ndrewffght, I don't really remember)
Last edited on
Thank you for all the replies. The issue was precisely those three variables. However, besides removing them from the header and adding them locally to main.cpp, I also had to declare them in clockTypeImp.cpp in order for the program to run because I kept getting an error about the getTime function requesting them, but the debugger told me that the variables had not been declared in that scope.

Even though the program runs now, I have noticed that I am getting what I imagine are memory addresses as the output for object myClock, something that wasn't happening when the whole thing was in a single file. The reason I had those variables declared globally was also because that's how I managed to make the program run before I split it into the three files.

ndrewxie: Hello. The book did mention what you said, and I hoped that CodeBlocks was properly linking the files, which, thankfully, it was. I did have the header included in main though. I should probably learn how to do it without relying on a external source, but I am feeling a bit overwhelmed as it is. I only have so much time.

Here's what I get as an output now:
1
2
3
4
5
6
The default myClock time is: 1988324058:-2:-233419117
The default yourClock time is: 00:00:00
The default oneClock time with one parameter declared is: 15:00:00
The default twoClock time with two parameters declared is: 05:25:00

Enter hours, minutes, and seconds in the format (h m s):


clock.h without variables:
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
#include <iostream>
#ifndef clockType_h
#define clockType_h

class clockType
{
public:
    void setTime (int, int, int); //Sets time to a given value.
    void getTime (int&, int&, int&) const;
    void printTime () const; //Prints time.
    void incrementSeconds(); //Increments time by 1 second.
    void incrementMinutes(); //Increments time by 1 minute.
    void incrementHours(); //Increments time by 1 hour.
    bool equalTime (const clockType&) const; //Compares equality
                                             //of two times.
    clockType(int = 0, int = 0, int =0);
    
    //Functions that overload the operators.
    bool operator==(const clockType& otherClock) const;
    bool operator!=(const clockType& otherClock) const;
    bool operator<(const clockType& otherClock) const;
    bool operator>(const clockType& otherClock) const;
    void operator=(const clockType& otherClock);

private:
    int hr;
    int min;
    int sec;
};

#endif  


Added variables to clockTypeImp.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include "clockType.h"
#ifndef clockType_Imp
#define clockType_Imp

//Variables used in setTime and getTime functions. It was necessary
//to declare them in this file and main.cpp as well in order for
//the program to work properly.
int hours;
int minutes;
int seconds;

using namespace std;
.
.
.


Variables added to 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
26
27
#include<iostream>
#include "clockType.h"

using namespace std;

int main()
{
//Variables used in setTime and getTime functions. It was necessary
//to declare them in this file and main.cpp as well in order for
//the program to work properly.
    int hours;
    int minutes;
    int seconds;

    clockType oneClock (15);
    clockType twoClock (5, 25);
    clockType yourClock;
    clockType equalClock;
    clockType myClock (12, 30, 30);

    cout << "The default myClock time is: ";
    myClock.getTime(hours, minutes, seconds);
    cout << hours << ":" << minutes << ":" << seconds;
    cout << endl;
.
.
.


If you check the part of the code I posted above, you will see that I do set myClock to receive 12, 30, 30, but now the program is not assigning those values any longer.

Note: I didn't post the whole code again because I can only post a max of 8192 characters here.
Last edited on
Actually, it seems like it is assigning, but the that first output is not outputting the proper values. Here is the full execution of the program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
The default myClock time is: 1988324058:-2:-233419117
The default yourClock time is: 00:00:00
The default oneClock time with one parameter declared is: 15:00:00
The default twoClock time with two parameters declared is: 05:25:00

Enter hours, minutes, and seconds in the format (h m s): 5 5 5

Time in objects myClock and yourClock is not equal by using equalTime function.
Time in objects myClock and yourClock is not equal by using != overloaded operator.
Time in objects myClock and yourClock is not equal by using == overloaded operator.
Time in object myClock is greater than time in object yourClock by using > overloaded operator.
Time in object myClock is not less than time in object yourClock by using < overloaded operator.

Time in myClock is: 12:30:30
The user updated yourClock time is: 05:05:05
Time in equalClock after using = overloaded operator: 05:05:05
Time in equalClock after incrementing seconds: 05:05:06
Time in equalClock after incrementing minutes: 05:06:06
Time in equalClock after incrementing hours: 06:06:06

Press any key and press enter to terminate the program:


Line 14 implies that myClock does get the values, so my issue must be with the getTime function maybe? The getTime function is the one that threw errors when I moved the global variables from the header and declared them locally in the main.cpp. I managed to take care of the error by declaring the same variables inside clockTypeImp.cpp. I am pretty sure that my issue must have to do with that, but now I am lost trying to figure out how to fix that particular function.
Last edited on
I figured it out myself. I had to name the formal parameters of the function getTime as (int& hours, int& minutes, int& seconds) and the variables should really only be local in the main. Thank you all for your help.
Topic archived. No new replies allowed.