Frage

Ich arbeite in C ++ und ich muß wissen, ob ein skalarer Wert (zum Beispiel eines double) wird „definiert“ ist oder nicht. Ich muß auch in der Lage sein „undefiniert“ es, wenn nötig:

class Foo {
public:
    double get_bar();

private:
    double bar;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( undefined(bar) )
        calculate_bar();
    return bar;
}

Ist es möglich, in C ++?

Danke

War es hilfreich?

Lösung

Wie die anderen Antworten sagen, C ++ nicht dieses Konzept hat. Sie können allerdings um es einfach arbeiten.

Sie können entweder einen nicht definierten Wert, die Sie bar im Konstruktor initialisieren, typischerweise -1,0 oder etwas ähnliches.

Wenn Sie wissen, dass calculate_bar nie negative Werte liefert Ihnen die nicht definierte Funktion als Kontrolle implementieren können für <0,0.

Eine allgemeine Lösung wird mit einer Bool sagen, ob bar definiert ist noch, dass Sie im Konstruktor auf false initialisiert und wenn Sie es zuerst legen Sie es auf true ändern. boost :: optional tut dies in eine elegante Art und Weise als Templat.

Dies ist, was das Codebeispiel Sie würde so aussehen haben.

class Foo {
public:
    double get_bar();
    Foo() : barDefined(false) {}
private:
    double bar;
    bool barDefined;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( barDefined == false ) {
        calculate_bar();
        barDefined = true;
    }
    return bar;
}

Andere Tipps

Wie andere erwähnt, gibt es nichts, wie ein „undefiniert“ Zustand. Sie können jedoch in boost.optional

Wenn Sie zur Laufzeit bedeutet, ist es nicht so etwas. Wenn bar nie initialisiert wird, wird es haben, was Zufallsbits da sein passiert, je nachdem, wie das Objekt zugeordnet ist (einige Verteilern neue Speicher, um alle von Null initialisieren).

edit: es ist bis zu dem Programmierer Objektzustand in Konstrukteuren und / oder manuellen Initialisierungsmethoden wie init()

zu handhaben

Warum eine separate Flag nicht halten, die auf false initialisiert werden und dann auf true gesetzt wird, wenn bar berechnet. Es kann dann wieder durch das Setzen der Flagge auf false ‚undefed‘ werden.

if(!isBarValid)
{
    calculateBar();
    isBarValid = true;
}
return bar;

C ++ nicht über einen „undefiniert“ Zustand für primitive Typen. Die zur Verfügung stehende Nähe für float / double würde NAN sein, aber das hat wirklich eine andere Bedeutung.

Dies ist nicht möglich in C / C ++, Primitive wird immer ein Wert zugewiesen (meist Müll, was auch immer, bevor es an dieser Stelle in Erinnerung war, sofern nicht explizit bei der Deklaration zugewiesen). I ist üblich, einen Platzhalter-Wert (das heißt 0 für Zeiger) zu haben, die nicht-verwendet wird, bezeichnet, aber diese auch explizit zugewiesen werden müssen. Wenn Ihr Doppel auf jeden beliebigen Wert annehmen kann, dann empfehle ich Ihnen einen boolean setzen daneben zugewiesen falsch zunächst und prüfen / einstellen, dass man, wenn Sie Ihre Berechnung tun wollen.

Sie müssen es tun, indem eine zusätzliche boolean verwendet wird.

Um eine zusätzliche boolean zu implementieren verwenden, können Sie Logik wie die folgende Vorlage versuchen:

template<typename T>
struct Defined
{
 bool defined;
 T value;
 Defined() : defined(false) {}
 Defined(const T& value_) : defined(true), value(value_) {}
 ... and perhaps other operators here ...
 ... to make this behave even more like a T ...
};

Sie könnten versuchen, die Konstruieren Sie bei der ersten Verwendung Idiom und schreiben get_bar() auf diese Weise:

double & get_bar()
{
    static double *bar = new double(something());
    return *bar;
}

Wenn Sie get_bar() nennen es bar für Sie, wenn noch niemand danach gefragt hat. Alle nachfolgenden Anrufe werden nur zurückkehren bar. Wie die verknüpfte Seite sagt, ist dieser Speicher nicht technisch auslaufen, da das O wird es zurückzufordern, wenn das Programm beendet wird.

UPDATE:

Changed den Rückgabewert double &, damit Sie bar ändern.

bar auf einen Wert initialisiert werden, die niemals auftreten, wenn Sie die something() Funktion im Konstruktor aufrufen.

Zum Beispiel:

Foo(): bar(-1)
{
}

Dann sind Sie für den Wert -1 in der get_bar Funktion.

(hmmm Laserallan auch geschrieben, dass Frage 1 Minute vor :-( ;-))

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top