tags:

views:

153

answers:

6

I'm trying to make the add_day function work, but I'm having some trouble. Note that I can't make any changes to the struct(it's very simplistic) because the point of the exercise is to make the program work with what's given. The code is

#include "std_lib_facilities.h"

struct Date{
       int y, m, d;
       Date(int y, int m, int d);
       void add_day(int n);
};

void Date::add_day(int n)
{
     d+=n;
}

ostream& operator<<(ostream& os, const Date& d)
{
         if(d.m<1 || d.m>12 || d.d<1 || d.d>31) cout << "Invalid date: ";
         return os << '(' << d.y
                   << ',' << d.m
                   << ',' << d.d << ')';
}

int main()
{
    Date today(1978,6,25);
    today.add_day(1);
    cout << today << endl;
    keep_window_open();
}

I'm getting a linker error that says undefined reference to Date::Date(int,int,int), but I can't figure out what's wrong. It seems like it's something to do with the Date constructor, but I'm not sure what.

I'd also like to add in a line of code for tomorrow like

Date tomorrow = today.add_day(1);

but I've got a feeling that since add_day is a void type there will be a conversion issue.

Any help would be appreciated - thanks.

P.S. Don't worry about adding days at the end of the month. It's something that's going to be implemented later.

+2  A: 

You've declared a constructor Date::Date(int,int,int), and called it, but there is no definition for it. Ergo, linker error.

Dave Costa
+2  A: 

Specifically to the errors you're getting:

1) You are defining a non-default constructor (i.e., one that gets three parameters). This is not generated automatically by the compiler, so you have to provide an implementation. That's why you get the link error.

I don't fully remember the C++ syntax, but it's something like this:

Date::Date(int _y, int _m, int _d):y(_y),m(_m),d(_d){}

2) What are the semantics of add_day? If add_day takes the date object it is invoked on and changes it, what exactly do you want to return? It doesn't have to be a void, you can define whatever you want, but think hard about what the most intuitive semantics are.

Maybe you want a function called createTomorrow(), that does not modify the current Date object, but insteadgenerates a new Date object, sets it to the appropriate date (all the same except for day), and then returns it.

Uri
+6  A: 

The linker error is because you are not defining the constructor.

Date::Date( int yr, int mo, int day ) : y(year), m(month), d(day)
{
}

For the add_day question: you are correct that you need to change the return type. It should return a Date object. You can construct a new Date object and return it with the day value incremented or just increment the day value and return *this.

Jesse
+2  A: 

The Date constructor is not defined. You can define it as something like this:

Date::Date(int y, int m, int d)
{
    this.y = y;
    this.m = m;
    this.d = d;
}
Robbie
+4  A: 

You have a constructor declared

Date(int y, int m, int d);

but you never wrote the definition for the constructor. Presumably you will want to add some code like

Date::Date(int y, int m, int d):y(y),m(m),d(d)
{
}

Additionally,

Date tomorrow = today.add_day(1);

Date::add_day(int) must return a new day for this to work.

Date Date::add_day(int n)
{
    d+=n;
    return *this;
}

This will return a copy of this after modifying it.

Nick Lewis
Generally we would return a const reference instead of a copy, same functionality but more efficient specially with time consuming copying (not so much an issue here).
DeusAduro
A: 

You declare the constructor of class Date with three parameters, but never define it.

You want to add a line like Date::Date(int yy, int mm, int dd) : y(yy), m(mm), d(dd) {}

And for the second question -- add_day would have to return Date or Date &

cube