-2

I have a date class like below which I use to find the resultant date after adding/subtracting a few days. The constructor validates the input date and throws an exception if invalid.

class date
{
    private:
        int day;
        int month;
        int year;

        bool isValid(date& d);

    public:
        date(); //default to starting of say Gregorian calendar
        date(string strDate); // takes DD/MM/YYYY format string to initialize day, month and year

        //static date today;

        int operator- (date& d); //difference of two dates in no. of days
        int operator- (int days); //get the date a few days before this date
        void operator+ (int days); //get the date a few days after this date
};

In addition to the above I also want to keep track of today's date as part of the class itself which other parts of the program can use for calculation purposes.

Is it possible to have a static member as written in the commented line above and have the class itself initialize the object?

If yes how do we initialize the object? If no then what is the correct way of dealing with the "today" object?

I read other posts but all posts seem to deal with static members of basic types. However here multiple statements has to executed in order to get system date and hence I am thinking it is different from the other posts.

kingvittu
  • 47
  • 8
  • 1
    What problem exactly are you encountering? Have you tried uncommenting the line? Is there a particular error you are trying to overcome? – François Andrieux Jul 03 '18 at 14:06
  • Sorry I could have been more clear. I have edited the question – kingvittu Jul 03 '18 at 14:15
  • Today object, eh? So you guarantee your program will never ever run from 23.59.59.9999 of one day to 00.00.00.0001 the next day? (Your edit clarified precisely nothing). – n. m. could be an AI Jul 03 '18 at 14:21
  • @n.m. `today` is not `const`. No reason it can't be updated daily. – François Andrieux Jul 03 '18 at 14:22
  • @FrançoisAndrieux Updating daily is a possibility, yeah. I find it somewhat easier to use today's date when it's spelled `today()` rather than `today`, but of course you can use the latter if you know what you are doing (what are the chances of that if you are asking how to initialise a static class member?) – n. m. could be an AI Jul 03 '18 at 14:33
  • @n.m. To begin with I was thinking of running the program as a one-shot utility without having to run continuously. – kingvittu Jul 05 '18 at 09:01

1 Answers1

1

You absolutely can uncomment the code, exactly as written. But that merely “declares” the variable. To “define” it, in exactly one source file (such as the .cpp/.cc file with the rest of the code), near the top (and outside all functions), put the line:

date date::today;

That defines the variable (like other class members are defined).

Note that only date methods can access it, since it’s private. If you want other parts of the program to be able to (only) read it, you can do one of two things:

  1. Add a public static method to the class:

    static const date &Today() { return today; }
    
  2. Add a second, public static variable inside the class which referred to the first - but then you have to worry about the two names.

    • Inside the class, change today to _today, and add:

      public:
         static const date &today;
      
    • And inside the .cpp/.cc you need to define them:

      date date::_today;
      const date &date::today = date::_today;
      

With that, inside the date class you can modify _today, while other parts of the program can read today.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
John Burger
  • 3,662
  • 1
  • 13
  • 23
  • This answer is a great start but appears incomplete to me, It doesn't address how to initialize `today` to a specific value, neither does it explain why the line `date date::today` is necessary or why it must be in a source file. – François Andrieux Jul 03 '18 at 14:23
  • @FrançoisAndrieux Not my code, and the OP hasn’t provided that info. Maybe the design updates the variable every time a `date` method is called. I’ve explained how to do what he’s asked in C++, and how to enhance his design for the stated wish of “other parts of the program”. I’ll edit to explain why `date date::today;` needs to be in the source. – John Burger Jul 03 '18 at 14:27
  • There's `date::date(string strDate)`. The string date can be obtained using the standard library. – n. m. could be an AI Jul 03 '18 at 14:37
  • Thanks for the answer. However I am interested in initialization of the object. There will be more than one line of code to execute to get the today's date from the OS and that is how it is different from initializing a basic data type variable. – kingvittu Jul 05 '18 at 09:25
  • I have edited my question and made the member public – kingvittu Jul 05 '18 at 09:32
  • That’s the beauty of having a static class member - it can use `private` methods. For example, to initialise it you can have a `private` constructor that takes a `bool`. No-one else can call it, but you can use `date date::_today(true);`. And to update it later, at any time you can have `date::_today = date(true);` The `bool` is merely a place-holder, to distinguish it from other constructors. Make sure you declare that constructor `explicit`! – John Burger Jul 05 '18 at 09:40
  • This seems to work. But the only problem I'm facing is I'm not able to reuse the functionality in other constructors. For example I get the current date in "DD/MM/YYYY" format string in this date(bool) constructor. But if I call date(string strDate) constructor to create a date object out of the string and then assign it to date::_today the day, month and year values are not copied but instead show junk values when accessed in main. – kingvittu Jul 05 '18 at 12:54
  • Have you written a `date &operator =(const date &);`? The line `*this = date(“04/07/2018”);` would require it... – John Burger Jul 05 '18 at 12:59
  • I did it as below but same result: `date& operator =(date& dt) { day = dt.day; month = dt.month; year = dt.year; return dt; }` – kingvittu Jul 05 '18 at 13:38
  • Ok I have a constructor date(int day,int month, int year) and I was not doing *this = date(day,month,year) inside date(string strDate). Instead I was just doing date(day,month,year);. So thanks for the *this = clue, that worked. Could you please update your answer with the solution you gave in earlier comment? I can then mark the answer as accepted. – kingvittu Jul 05 '18 at 14:02