2017-03-28 1 views
1

En essayant simplement de suivre le livre sur un auto-apprentissage C++.Opérateur de surcharge C++ - pour soustraire deux objets du même type

Ce que j'ai jusqu'à présent est un programme que j'ai créé qui a un objet de Date, qui a quatre paramètres. Les trois paramètres remplis par l'utilisateur sont "Mois", "Jour" et "Année". Le quatrième paramètre est "Vieux", et c'est pour stocker combien de jours il est. Pour cela, j'ai écrit une fonction qui calcule combien de jours il est, et le définit comme le quatrième paramètre.

Cette partie fonctionne. Il calcule combien de jours il est. Le livre veut que je soustrais deux objets de type Date et découvre la différence entre leur âge. Pour cela, il demande spécifiquement que je crée un opérateur surchargé de (-), et soustrais les deux. C'est là que je me bloque un peu. La partie avec laquelle je suis en difficulté est, je crois, l'appel qui est utilisé pour y accéder. Je continue d'obtenir l'erreur de "surcharge ambiguë" pour l'opérateur "(les types d'opérande sont" Date "et" Date ").

Il reconnaît les deux objets en tant que date. Maintenant, j'ai juste besoin d'un peu d'aide pour la dernière étape.

J'ai essayé d'utiliser plusieurs choses différentes dans l'en-tête, mais peut-être que je ne les applique pas correctement.

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

Si vous pouvez aider avec ceci, ce serait merveilleux. Je suis nouveau, et j'ai passé plus de 12 heures sur cette 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<< 
+1

Vous pourriez vouloir vérifier par exemple [cette référence sur les implémentations canoniques pour les opérateurs surchargés] (http://en.cppreference.com/w/cpp/language/operators#Canonical_implementations)? Surtout la [section qui montre les opérateurs arithmétiques binaires] (http://en.cppreference.com/w/cpp/language/operators#Binary_arithmetic_operators). –

+0

@Someprogrammerdude Merci. La section principale de ce qui suggère d'utiliser un ami, alors j'ai modifié l'en-tête pour l'inclure, et a changé la fonction pour être ... ami Date opérateur - (Date et date1, Date & Date2) Malheureusement, je reçois l'erreur de "'ami' utilisé en dehors de la classe." – Greg

+0

En quoi est-ce différent de la question d'hier? http://stackoverflow.com/questions/43041663/overloading-a-minus-operator-to-determine-the-days-between-two-dates-in-c –

Répondre

0

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; 
} 
2

Définir vos opérateurs arithmétiques binaires (par exemple -) en utilisant votre opérateurs d'affectation de composés (par exemple -=). Vous pouvez jeter un oeil à cette référence binary arithmetic operator:

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 
} 
+0

Pour le bit supérieur, le compilateur se plaignait qu'il avait besoin de deux paramètres. Pour cela, puisque seul l'ancien paramètre devait être mis à jour, la partie supérieure serait-elle ... Date et opérateur - = (Date lhs, const Date & rhs) { lhs = lhs.old - rhs.old; retour lhs; } Il ne me donne pas d'erreurs quand je fais cela. Cela me donnait une erreur à propos d'un ami, où il était utilisé en dehors des cours. Cela voudrait-il dire qu'il devrait rester dans le fichier d'en-tête? J'ai enlevé l'ami de lui pour voir si cela fonctionnerait mais obtenir cette erreur surcharge ambiguë pour 'opérateur-' (les types d'opérande sont 'Date' et 'Date') | – Greg