简体   繁体   中英

C++ Overload operator - to subtract two objects of the same type

Just trying to follow the book on a self-paced learn C++.

What I have so far is a program that I have created that has an object of Date, which has four parameters. The three parameters that are filled out by the user are, "Month", "Day", and "Year". The fourth parameter is "Old", and that is to store how many days old it is. For that, I have written a function that calculates how many days old it is, and sets it as the forth parameter.

This part works. It calculates how many days old it is.

The book wants me to subtract two objects of type Date and find out the difference between how old they are. For that it specifically requests that I create an overloaded operator of (-), and subtract the two. This is where I am getting a little stuck. The part that I am having issues with is, I believe, the call that is used to access it. I continue to get the error of "ambiguous overload for "operator-' (operand types are 'Date' and 'Date').

It recognizes both objects as Date. Now I just need a little help for the last leg of this.

I have tried using several different things in the header, but perhaps I am implementing them incorrectly.

-friend Date operator - (Date &ob1, Date &ob2);
-Date &operator-();
-Date &operator-(Date);
-Date operator-(Date);

If you can help out with this, it would be wonderful. I'm new, and I've spent over 12 hours on this on question.

Main.cpp

#include <iostream>
#include <time.h>
#include <ctime>
#include "Date.cpp" // Date class definition
using namespace std;

int main() {
    unsigned int birthMonth = 0;
    unsigned int birthDay = 0;
    unsigned int birthYear = 0;

    unsigned int dateToMonth = 0;
    unsigned int dateToDay = 0;
    unsigned int dateToYear = 0;

    cout << "Enter birth month (1-12): ";
    cin >> birthMonth;
    cout << "Enter birth day (1-31): ";
    cin >> birthDay;
    cout << "Enter birth year (1900 - 2000): ";
    cin >> birthYear;

    Date birthDate (birthMonth, birthDay, birthYear);
    Date tempDate (1, 1, 1, 1);

    cout << "To which date would you like to calculate to?\nEnter Day month (1-12): ";
    cin >> dateToMonth;
    cout << "Enter Day to calculate it to (1-31): ";
    cin >> dateToDay;
    cout << "Enter Year to calculate it to: ";
    cin >> dateToYear;

    Date dateTo (dateToMonth, dateToDay, dateToYear);

    pastDays(birthDate);
    pastDays(dateTo);

    cout << "\nHow many days ago is the birth date? " << birthDate.old << endl;
    cout << "How many days ago is the secondary date? " << dateTo.old << endl;

    // Here is where I get an error "ambiguous overload for "operator-' (operand types are 'Date' and 'Date')"
    cout << tempDate = birthDate - dateTo << endl;
    cout << tempDate.old;
}

Date.h

#ifndef DATE_H
#define DATE_H
#include <array>
#include <iostream>

class Date
  {
    friend std::ostream &operator<<( std::ostream &, const Date & );
public:
    Date( int m = 1, int d = 1, int y = 1900, int o = 0 ); // default constructor
    void setDate( int, int, int, int ); // set month, day, year
//    friend Date operator - (Date &ob1, Date &ob2);
    Date &operator-(); // Modified Line for Assignment
    Date &operator-(Date); // Modified Line for Assignment
//    Date operator-(Date);
    void pastDays (Date);
    static bool leapYear( int ); // is date in a leap year?
    unsigned int month;
    unsigned int day;
    unsigned int year;
    int old;
    static const std::array< unsigned int, 13 > days; // days per month
}; // end class Date

#endif

Date.cpp

#include <iostream>
#include <string>
#include "Date.h"
#include <time.h>
#include <ctime>
#include <conio.h>
#include "Date.h" // Date class definition
using namespace std;

   // initialize static member; one classwide copy
const array< unsigned int, 13 > Date::days = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

// Date constructor
Date::Date( int month, int day, int year, int old )
  {
    setDate( month, day, year, old );
  } // end Date constructor

// set month, day and year
void Date::setDate( int mm, int dd, int yy, int old )
  {
    if ( mm >= 1 && mm <= 12 )
        month = mm;
    else
        throw invalid_argument( "Month must be 1-12" );

    if ( yy >= 1900 && yy <= 2100 )
        year = yy;

    // test for a leap year
//        if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12){
//            if (dd >= 1 || dd <= 31)
//            day == dd;
//        }
//        if (month == 4 || month == 6 || month == 9 || month == 11){
//            if (dd >= 1 || dd <= 30)
//            day == dd;
//        }
//        if (month == 2)
//            if ( year % 4 != 0 ) {
//                if (dd >= 1 || dd <= 29)
//                day == dd;
//            }
//        if (month == 2)
//            if ( year % 4 != 0 ) {
//                if (dd >= 1 || dd <= 28)
//                day == dd;
//            }
//        else {
//            throw invalid_argument(
//                "Day is out of range for current month and year" );
//        }

    if ( ( month == 2 && leapYear( year ) && dd >= 1 && dd <= 29 ) ||
        ( dd >= 1 && dd <= days[ month ] ) )
        day = dd;
    else
        throw invalid_argument(
            "Day is out of range for current month and year" );


} // end function setDate

void pastDays (Date &entryDay) {
    //Creating Today date object
    time_t t = time(0);
    struct tm * now = localtime(&t);
    int currentYear = now -> tm_year + 1900;
    int currentMonth = now -> tm_mon + 1;
    int currentDay = now -> tm_mday;

    int birthMonth = entryDay.month;
    int birthDay = entryDay.day;
    int birthYear = entryDay.year;

    //The variable that will be assigned to the old parameter, which can then be subtracted from another time.
    int daysAgo = 0;
    entryDay.old = 0;

    cout << endl;
    cout << "First" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Lowering days to 1, to make transition between years easier.
//    while (birthDay > 1){
//        birthDay--;
//        daysAgo--;
//    }

    daysAgo = daysAgo - birthDay;
    daysAgo++;
    birthDay = 1;

    cout << endl;
    cout << "Second" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Lowering months to 1, to make transition between years easier.
    while (birthMonth > 1){
        if (birthMonth == 1 || birthMonth == 3 || birthMonth == 5 || birthMonth == 7 || birthMonth == 8 || birthMonth == 10 || birthMonth == 12){
            birthMonth--;
            daysAgo -= 31;
        }
        if (birthMonth == 4 || birthMonth == 6 || birthMonth == 9 || birthMonth == 11){
            birthMonth--;
            daysAgo -= 30;
        }
        if (birthMonth == 2)
            if ( currentYear % 400 == 0 ||
            ( currentYear % 100 != 0 && currentYear % 4 == 0 ) ) {
    birthMonth--;
    daysAgo -= 29;
            }
        else {
            birthMonth--;
            daysAgo -= 28;
        }
    }

    cout << endl;
    cout << "Third" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Incrementing year to current year
    while (birthYear < currentYear){
        if ( currentYear % 400 == 0 ||
        ( currentYear % 100 != 0 && currentYear % 4 == 0 ) ) {
            daysAgo = daysAgo + 366;
            birthYear++;
        }
        else {
            daysAgo = daysAgo + 365;
            birthYear++;
        }
    }

    cout << endl;
    cout << "Fourth" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    // Incrementing to current month
    while (birthMonth < currentMonth) {
        if (birthMonth == 1 || birthMonth == 3 || birthMonth == 5 || birthMonth == 7 || birthMonth == 8 || birthMonth == 10 || birthMonth == 12){
            birthMonth++;
            daysAgo += 31;
        }
        if (birthMonth == 4 || birthMonth == 6 || birthMonth == 9 || birthMonth == 11){
            birthMonth++;
            daysAgo += 30;
        }
        if (birthMonth == 2)
            if ( currentYear % 400 == 0 ||
            ( currentYear % 100 != 0 && currentYear % 4 == 0 ) ) {
    birthMonth++;
    daysAgo += 29;
            }
        else {
            birthMonth++;
            daysAgo += 28;
        }
    }

    cout << endl;
    cout << "Fifth" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Incrementing to current day, and adding the days to the daysAgo
    while (birthDay < currentDay){
        birthDay++;
        daysAgo++;
    }


    cout << endl;
    cout << "Sixth" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Assigning DaysAgo to input parameter.old
    entryDay.old = daysAgo;
}


    Date operator  - (Date &date1, Date &date2)
    {

    Date temp;
    temp.old   = date1.old   - date2.old;
    if(temp.old < 0)
    {
        temp.old = temp.old * -1;
    }
    return(temp);
    }

//Date operator-(Date birthDate)
////friend Distance operator - (Date &birthDate, Date &today)
//    {
////    int birthMonth = birthDate.month;
////    int birthDay = birthDate.day;
////    int birthYear = birthDate.year;
////    int birthOld = 0;
////    Date temp (birthDate.month, birthDate.day, birthDate.year, birthDate.old);
//
////    pastDays(today);
////    pastDays(birthDate);
//
////    int currentMonth = today.month;
////    int currentDay = today.day;
////    int currentYear = today.year;
//
////    int date1 = pastDays(today);
////    int date2 = pastDays(birthDate);
//    Date temp (birthDate.month, birthDate.day, birthDate.year);
//
////    int month, int day, int year, int old
////    temp.month = this -> month;
////    temp.month = this -> day;
////    temp.month = this -> year;
////    Date temp = *this;
//    cout << temp.old;
//
//    temp.old = *this -> old - birthDate.old;
//        //Here I get "Error: Invalid use of 'this' in non-member function;
//
//    return(temp);
//}

bool Date::leapYear( int testYear )
{
    if ( testYear % 400 == 0 ||
      ( testYear % 100 != 0 && testYear % 4 == 0 ) )
        return true; // a leap year
    else
        return false; // not a leap year
} // end function leapYear

// overloaded output operator
ostream &operator<<( ostream &output, const Date &d )
{
  static string monthName[ 13 ] = { "", "January", "February",
        "March", "April", "May", "June", "July", "August",
        "September", "October", "November", "December" };
  output << monthName[ d.month ] << ' ' << d.day << ", " << d.year;
  return output; // enables cascading
} // end function operator<<

Define your binary arithmetic operators (eg - ) using your compound assignment operators (eg -= ). You may want to take a look at this binary arithmetic operator reference:

Date& operator-=(const X& rhs) {                           
  /* subtraction of rhs to *this takes place here */
  this->year - rhs.year; // This is the easy one

  /* Here you will have to play around with this->month and this->day */

  return *this; // return the result by reference
}


friend Date operator-(Date lhs, const Date& rhs) {
  lhs -= rhs; // use compound assignment
  return lhs; // return the result by value
}

main.cpp

#include <iostream>
#include <time.h>
#include <ctime>
#include "Date.cpp" // Date class definition
using namespace std;

int main() {
    unsigned int birthMonth = 0;
    unsigned int birthDay = 0;
    unsigned int birthYear = 0;

    unsigned int dateToMonth = 0;
    unsigned int dateToDay = 0;
    unsigned int dateToYear = 0;

    cout << "Enter birth month (1-12): ";
    cin >> birthMonth;
    cout << "Enter birth day (1-31): ";
    cin >> birthDay;
    cout << "Enter birth year (1900 - 2000): ";
    cin >> birthYear;

    Date birthDate (birthMonth, birthDay, birthYear);
    Date tempDate (1, 1, 1, 1);

    cout << "To which date would you like to calculate to?\nEnter Day month (1-12): ";
    cin >> dateToMonth;
    cout << "Enter Day to calculate it to (1-31): ";
    cin >> dateToDay;
    cout << "Enter Year to calculate it to: ";
    cin >> dateToYear;

    Date dateTo (dateToMonth, dateToDay, dateToYear);

    pastDays(birthDate);
    pastDays(dateTo);

    cout << "\nHow many days ago is the birth date? " << birthDate.old << endl;
    cout << "How many days ago is the secondary date? " << dateTo.old << endl;

    tempDate = birthDate - dateTo;
    cout << tempDate.old;
}

Date.h

#ifndef DATE_H
#define DATE_H
#include <array>
#include <iostream>

class Date
  {
    friend std::ostream &operator<<( std::ostream &, const Date & );
//  friend Date operator-(Date, Date);
public:
    Date( int m = 1, int d = 1, int y = 1900, int o = 0 ); // default constructor
    void setDate( int, int, int, int ); // set month, day, year
//  friend Date operator-(Date, Date);
    Date operator-(); // Modified Line for Assignment
    Date operator-(Date); // Modified Line for Assignment
//    Date operator-(Date);
    void pastDays (Date);
    static bool leapYear( int ); // is date in a leap year?
    unsigned int month;
    unsigned int day;
    unsigned int year;
    int old;
    static const std::array< unsigned int, 13 > days; // days per month
}; // end class Date

#endif

Date.cpp

#include <iostream>
#include <string>
#include "Date.h"
#include <time.h>
#include <ctime>
#include <conio.h>
#include "Date.h" // Date class definition
using namespace std;

   // initialize static member; one classwide copy
const array< unsigned int, 13 > Date::days = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

// Date constructor
Date::Date( int month, int day, int year, int old )
  {
    setDate( month, day, year, old );
  } // end Date constructor

// set month, day and year
void Date::setDate( int mm, int dd, int yy, int old )
  {
    if ( mm >= 1 && mm <= 12 )
        month = mm;
    else
        throw invalid_argument( "Month must be 1-12" );

    if ( yy >= 1900 && yy <= 2100 )
        year = yy;

    if ( ( month == 2 && leapYear( year ) && dd >= 1 && dd <= 29 ) ||
        ( dd >= 1 && dd <= days[ month ] ) )
        day = dd;
    else
        throw invalid_argument(
            "Day is out of range for current month and year" );


} // end function setDate

void pastDays (Date &entryDay) {
    //Creating Today date object
    time_t t = time(0);
    struct tm * now = localtime(&t);
    int currentYear = now -> tm_year + 1900;
    int currentMonth = now -> tm_mon + 1;
    int currentDay = now -> tm_mday;

    int birthMonth = entryDay.month;
    int birthDay = entryDay.day;
    int birthYear = entryDay.year;

    //The variable that will be assigned to the old parameter, which can then be subtracted from another time.
    int daysAgo = 0;
    entryDay.old = 0;

    cout << endl;
    cout << "First" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Lowering days to 1, to make transition between years easier.
//    while (birthDay > 1){
//        birthDay--;
//        daysAgo--;
//    }

    daysAgo = daysAgo - birthDay;
    daysAgo++;
    birthDay = 1;

    cout << endl;
    cout << "Second" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Lowering months to 1, to make transition between years easier.
    while (birthMonth > 1){
        if (birthMonth == 1 || birthMonth == 3 || birthMonth == 5 || birthMonth == 7 || birthMonth == 8 || birthMonth == 10 || birthMonth == 12){
            birthMonth--;
            daysAgo -= 31;
        }
        if (birthMonth == 4 || birthMonth == 6 || birthMonth == 9 || birthMonth == 11){
            birthMonth--;
            daysAgo -= 30;
        }
        if (birthMonth == 2)
            if ( currentYear % 400 == 0 ||
            ( currentYear % 100 != 0 && currentYear % 4 == 0 ) ) {
    birthMonth--;
    daysAgo -= 29;
            }
        else {
            birthMonth--;
            daysAgo -= 28;
        }
    }

    cout << endl;
    cout << "Third" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Incrementing year to current year
    while (birthYear < currentYear){
        if ( currentYear % 400 == 0 ||
        ( currentYear % 100 != 0 && currentYear % 4 == 0 ) ) {
            daysAgo = daysAgo + 366;
            birthYear++;
        }
        else {
            daysAgo = daysAgo + 365;
            birthYear++;
        }
    }

    cout << endl;
    cout << "Fourth" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    // Incrementing to current month
    while (birthMonth < currentMonth) {
        if (birthMonth == 1 || birthMonth == 3 || birthMonth == 5 || birthMonth == 7 || birthMonth == 8 || birthMonth == 10 || birthMonth == 12){
            birthMonth++;
            daysAgo += 31;
        }
        if (birthMonth == 4 || birthMonth == 6 || birthMonth == 9 || birthMonth == 11){
            birthMonth++;
            daysAgo += 30;
        }
        if (birthMonth == 2)
            if ( currentYear % 400 == 0 ||
            ( currentYear % 100 != 0 && currentYear % 4 == 0 ) ) {
    birthMonth++;
    daysAgo += 29;
            }
        else {
            birthMonth++;
            daysAgo += 28;
        }
    }

    cout << endl;
    cout << "Fifth" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Incrementing to current day, and adding the days to the daysAgo
    while (birthDay < currentDay){
        birthDay++;
        daysAgo++;
    }


    cout << endl;
    cout << "Sixth" << daysAgo << endl;
    cout << "BirthMonth: " << birthMonth << endl;
    cout << "BirthDay: " << birthDay << endl;
    cout << "BirthYear: " << birthYear << endl;

    //Assigning DaysAgo to input parameter.old
    entryDay.old = daysAgo;
}

bool Date::leapYear( int testYear )
{
    if ( testYear % 400 == 0 ||
      ( testYear % 100 != 0 && testYear % 4 == 0 ) )
        return true; // a leap year
    else
        return false; // not a leap year
} // end function leapYear

// overloaded output operator
ostream &operator<<( ostream &output, const Date &d )
{
  static string monthName[ 13 ] = { "", "January", "February",
        "March", "April", "May", "June", "July", "August",
        "September", "October", "November", "December" };
  output << monthName[ d.month ] << ' ' << d.day << ", " << d.year;
  return output; // enables cascading
} // end function operator<<

Date Date::operator-(Date rhs) {
  //lhs -= rhs; // use compound assignment
  //return lhs; // return the result by value
  Date n = *this;
  n.old -= rhs.old;
  return n;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM