Seite 2 von 2

Re: Wie vergleiche ich 2 Daten(Datum) ?

Verfasst: Sonntag 21. April 2013, 14:52
von BlackJack
@desmater: Da C++ eine Programmiersprache mit OOP-Unterstützung und Klassen ist, gibt es da sicher Ähnlichkeiten.

Die Methoden mit den beiden führenden und abschliessenden Unterstrichen sind von der Sprache vorgesehene Methodennamen die besonders sind, weil sie das Verhalten der Objekte im Zusammenspiel mit der Sprache beeinflussen. `__repr__()` dient beispielsweise dazu eine Zeichenkettenrepräsentation des Objekts für Programmierer zu liefern. Da lege ich also fest wie das Objekt aussieht wenn man es mit `repr()` in eine Zeichenkette umwandelt, und damit indirekt wie es bei ``print`` ausgegeben wird (wenn keine `__str__()`-Methode implementiert wird) oder wie es in der Zeichenkettendarstellung aussieht wenn es in einer Liste oder einem der anderen Grunddatentypen als Wert steckt.

Die `__cmp__()`-Methode wird verwendet wenn das Objekt mit einem anderen verglichen wird. In der `age_in_days()`-Funktion steht der Ausdruck ``if today > birth_date:`` und Python muss dann ja irgendwie entscheiden können ob das Datum von heute tatsächlich grösser als das Geburtsdatum ist. Für diese Entscheidung wird die `__cmp__()`-Methode heran gezogen. Das ist sozusagen *eine* Operatorüberladung für gleich mehrere Operatoren (``==``, ``!=``, ``<``, ``>``, ``<=``, und ``>=``). Diese „magischen” Methoden sind in der Python-Dokumentation beschrieben. Im Gegensatz zu C++ lässt sich mehr Verhalten überschreiben als nur Operatoren.

Mal spasseshalber das ganze in C++, allerdings ohne die Benutzereingabe:

Code: Alles auswählen

#include <ostream>

class Date
{
    friend std::ostream& operator<< (std::ostream& out, const Date& date);

private:
    static const int DAYS_PER_MONTH[];
    int m_year;
    int m_month;
    int m_day;

    Date() {}

public:
    explicit Date(int year, int month, int day)
        : m_year(year), m_month(month), m_day(day) {}
    bool operator != (const Date& date) const;
    Date& operator ++ (int);
    int getYear() const { return m_year; }
    int getMonth() const {return m_month; }
    int getDay() const {return m_day; }
    bool isLeapYear() const;
    int getDaysInMonth() const;
    int countDaysTo(const Date& other) const;
    static Date today();
};
Bei '&' bitte ein einfaches '&' vorstellen… Dieser Sch@%§&…-Syntax-Highlighter.

Code: Alles auswählen

#include <ctime>
#include <iostream>
#include "test.h"

const int Date::DAYS_PER_MONTH[] = {
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

std::ostream& operator << (std::ostream& out, const Date& date)
{
    out << date.m_day << '.' << date.m_month << '.' << date.m_year;
    return out;
}

bool Date::operator != (const Date& other) const
{
    return m_year != other.m_year
        || m_month != other.m_month
        || m_day != other.m_day;
}

Date& Date::operator ++ (int)
{
    int last = getDaysInMonth();
    if (m_day < last) {
        m_day++;
    } else if (m_day == last) {
        if (m_month < 12) {
            m_month++;
            m_day = 1;
        } else {
            m_year++;
            m_month = m_day = 1;
        }
    }
    return *this;
}

bool Date::isLeapYear() const
{
    return m_year % 4 == 0 && (m_year % 100 != 0 || m_year % 400 == 0);
}

int Date::getDaysInMonth() const
{
    int result = DAYS_PER_MONTH[m_month - 1];
    if (m_month == 2 && isLeapYear()) result++;
    return result;
}

int Date::countDaysTo(const Date& other) const
{
    int result = 0;
    Date current = *this;
    while (current++ != other) result++;
    return result;
}

Date Date::today()
{
    time_t t = time(NULL);
    struct tm *tm = localtime(&t);
    Date result(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
    return result;
}

int main()
{
    Date today = Date::today();
    Date birth_date = Date(1999, 9, 9);

    std::cout << "Vom " << birth_date << " bis " << today << " sind "
        << birth_date.countDaysTo(today) << " Tage vergangen." << std::endl;
    
    return 0;
}
Edit: Anmerkungen von bwbg umgesetzt.

Re: Wie vergleiche ich 2 Daten(Datum) ?

Verfasst: Sonntag 21. April 2013, 19:06
von bwbg
Wenn Du jetzt noch eine Initialisierungsliste nähmest und den zweiten Operand von operator<< als const reference übergäbest, dann wärs perfekt :P

Wobei ich friends nicht mag, was aber mehr persönlich als sachlich begründet ist.

Grüße ... bwbg

PS: void muss bei parameterlosen Funktionen (hier: main) nicht angegeben werden.
PPS: Default-Constructor und explicit sollten auch noch rein.

Re: Wie vergleiche ich 2 Daten(Datum) ?

Verfasst: Sonntag 21. April 2013, 20:07
von BlackJack
@bwbg: Soso, Du magst also keine Freunde. ;-)

Das ``void`` bei `main()` ist in meiner C-Vorlage so drin gewesen. Habe ich vergessen rauszunehmen.

Warum die Initialisierungsliste? Ich hatte ganz naiv angenommen, dass ein Compiler hier in beiden Fällen den gleichen Code erzeugt und deshalb wollte ich „Syntax sparen”. Davon hat C++ sowieso viel zu viel. IMHO. :-) ``explicit`` kannte ich noch gar nicht.

Re: Wie vergleiche ich 2 Daten(Datum) ?

Verfasst: Sonntag 21. April 2013, 20:30
von lunar
@bwbg Wieso "explicit"? In C++03 wird dieses Schlüsselwort bei Konstruktoren mit mehreren Argumenten ignoriert. In C++ 11 bringt man sich damit um die syntaktisch schöne Möglichkeit der Brace Initialization: "Date foo = {2012, 04, 21}".

Re: Wie vergleiche ich 2 Daten(Datum) ?

Verfasst: Sonntag 21. April 2013, 20:53
von bwbg
"brace initialization" ist nun auch mir neu. Ich habe mir bisher immer eintrichtern lassen, dass explicit eher gesetzt als weg gelassen werden sollte. Ich muss mir wirklich mal alle Änderungen zu C++11 zu Gemüte führen ... wäre nicht C++ so verdammt zeitaufwändig.

Zu Freunden: Ich empfinde das immer als "Hack", einer globalen Funktion die Internas einer Klasse zu offenbaren. Bisher habe ich z. B. eine std::ostream& immer an eine Methode weitergeleitet.

Grüße ... bwbg