Duplicate symbol error

I am new to c++ and programming in general. Thus, please excuse me if this question seems trivial but I would appreciate anyone's help.

I am learning object oriented programming and I decided to create a date program separated in 3 files. However, when I run my program I get the following error:

ld: 17 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Testing] Error 1

My question is: how can I fix this duplicate symbol error? here is my code. I tried to comment it out as much as possible to make it easier for whoever might want read it

header file
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
 #ifndef CHRONO_H_
#define CHRONO_H_
#include<sstream>

using namespace std;
namespace Chrono { // name space for class and helper functions
enum  class Month { //enum for the months of date class
	jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec
};
class Date {
	 int day, year;
	 Month month;
public:
	Date();
	Date(Month m, int d, int y);
	int getDay() const;
	Month getMonth() const;
	int getYear() const;
	void addDay (int d);
	void addMonth(Month m);
	void addYear(int n);
};
bool leapYear(int y); // to identify a leap year
bool isDate(Month m, int d, int y); // returns true if the date has the right month and right days of month
Month& operator ++(Month& m); // to add one to enum and get to next month
bool operator ==(Date& a, Date& b);
bool operator != (Date& a, Date& b);
ostream& operator <<(ostream& os, Date& d);
istream& operator >>(istream& is, Date& dd);
}
#endif /* CHRONO_H_ */ 

definitions.
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
  #include <iostream>
#include "Chrono.h"

using namespace std;
//definitions
namespace Chrono {
int Date:: getDay() const {return day;}
Month Date::getMonth() const {return month;}
int Date::getYear() const {return year;}
bool leapYear(int y) {
	if (y % 4 == 0) return true;
	return false;
}
bool isDate(Month m, int d, int y) {
	if(d <= 0) return false;
	if (m < Month::jan || m > Month::dec) return false;
	int daysInMonth = 0;
		switch (m) {
		case Month::feb:
			if (leapYear(y)) {
				daysInMonth = 29;
			} else {
				daysInMonth = 28;
			}
			break;
		case Month::apr: case Month::jun: case Month::sep: case Month::nov:
			daysInMonth = 30;
			break;
		case Month::jan: case Month::mar: case Month::may: case Month::jul: case Month::aug: case Month::oct: case Month::dec:
			daysInMonth = 31;
		}

	if (d  > daysInMonth) return false;

	return true;
}
Month& operator ++(Month& m) { // to add one to month and make sure it comes back to jan after dec
	m = (m == Month::dec) ? Month::jan: Month(int(m) + 1);
	return m;
}
bool operator ==(Date& a, Date& b) {
	return a.getDay() == b.getDay()
			&& a.getMonth() == b.getMonth()
			&& a.getYear() == b.getYear();
}
bool operator != (Date& a, Date& b) {
	return a.getDay() != b.getDay()
			&& a.getMonth() != b.getMonth()
			&& a.getYear() != b.getYear();
}
ostream& operator <<(ostream& os, Date& d) {
	os <<int (d.getMonth()) <<"/"
		<<d.getDay() <<"/"
		<<d.getYear();
	return os;
}
istream& operator >>(istream& is, Date& dd) {
	int d, m, y;
	char c1, c2;
	is >> m >> c1 >> d >> c2 >> y;
	if (c1 != '/' || c2 != '/') {
		is.clear(ios::failbit); // If wrong format, set the fail bit
		return is;
	}
	dd = Date (Month (m), d, y);
	return is;
}
Date::Date(): day(1), year(2001), month(Month::jan) {} // default constructor
Date::Date(Month m, int d, int y) {
	if (isDate(m, d, y)) {
		month = m;
		day = d;
		year = y;
	}else {
		cerr<<"This is not a valid date";
	}
}
void Date::addDay(int d) { //add day to date  but check if it woulc create a valid date first
	if (isDate(month, d, year)) d++;
}
void Date::addMonth(Month m) {// go to next month with overloaded ++ but check month first
	if (m < Month::jan || m > Month::dec) {
		cerr<<"This is not a valid month"<<endl;
	} else {
		++m;
	}
}
void Date::addYear(int n) {
	// check if current year is leap year before adding 1. If so, date is changed to mar 1, year+1
	if (month == Month::feb && day == 29 && !leapYear(year + n)) {
		month = Month::mar;
		day = 1;
	}
	year += n;
}
}

my main:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include "Chrono.h"
#include "Chrono.cpp"

using namespace std;
using namespace Chrono;

int main () {
	Date d1;
	cout<<d1;

return 0;
}


originally I had my getter function for the date class defined inside the class declaration and the run time error would say 14 duplicates instead of 17. I assume that it has to do with my data members and parameter values being duplicated each time I #include Chrono.h. I found a post online saying that creating a static data member and member function might help but I am not entirely sure how that would work.

Thank you for reading through my post and I apologize for it being so lenghty.
Last edited on
Hi,

Just a stab in the dark:

Don't include cpp files, just the header file is sufficient.

Try and get rid of using namespace std; that is an easy way to generate conflicts. Put std:: before each std thing.

With the days in a month thing, it's easier to look up an array of month values with a subscript of the month number.

For Leap Years, there is more to it than that: every 4 years is, every 100 is not, every 400 is.

(year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
Last edited on
wow! I can't believe it was so simple. Thanks a a lot for your advice! I know it can be a somewhat tedious to go through someone's code so I appreciate it.
Topic archived. No new replies allowed.