2014-05-05 11 views
11

Ho creato un oggetto che agisce in qualche modo come infinito per lunghi int. In particolare:Definizione di un oggetto che si comporta come un numero intero infinito

#ifndef MU_INF_H 
#define MU_INF_H 
#include "mu.h" 
namespace mu { 
    class Inf { 
    public: 
    bool operator> (long int i) { return true; } 
    bool operator> (Inf i) { return false; } 
    ... lots of other boolean operators ... 
    Inf& operator+ (long int i) { return *this; } 
    Inf& operator+ (Inf i) { return *this; } 
    ... lots of other integer operators ... 
    }; // class Inf 
}  // namespace mu 
#endif 

E tutto questo funziona piuttosto bene, che mi permette di eseguire unit test del modulo:

mu::Inf inf; 
    long int n = -1; 
    long int z = 0; 
    long int p = 1; 

    ASSERT((inf + inf) == inf); 
    ASSERT((inf + n) == inf); 
    ASSERT((inf + z) == inf); 
    ASSERT((inf + p) == inf); 

    ASSERT((inf > inf) == false); 
    ASSERT((inf > n) == true); 
    ASSERT((inf > z) == true); 
    ASSERT((inf > p) == true); 

A rischio di rendere impossibile assegnare un segno di spunta, ho tre domande:

  • Il C++ fornisce già qualcosa del genere e/o esiste un modo migliore di quello che sto facendo qui?
  • Desidero rendere disponibile un'istanza Inf all'interno del mio sistema. Non posso dichiararlo un static const perché non è un oggetto "semplice". Qual è l'approccio giusto: globale? modello singleton?
  • C'è un modo per gestire gli operatori simmetrici in cui il primo int arriva per primo, ovvero ASSERT((1 + inf) == inf)? (Non sarò troppo triste se non c'è.)
+0

cosa intendi? Non è un oggetto "semplice"? –

+1

Potresti ricevere assistenza migliore su codereview.stackexchange se il tuo codice funziona e desideri consigli su come migliorarlo. – ApproachingDarknessFish

+0

@BryanChen: Intendo dire che non posso fare 'const const Inf = kInfinity = new Inf()' o qualcosa di simile per renderlo una costante statica. –

risposta

5

static const Inf kInfinity; lavori e utilizzerà il costruttore di default.

operator+ dovrebbe essere una funzione libera che restituisce per valore:

Inf operator+(Inf a, Inf b) { return a += b; } 

È indicato che si preferisce restituire un riferimento a kInfinity invece di un valore. Questo è possibile (anche se mi sembra un po 'ingombrante); un riferimento a const dovrebbe essere restituito, ovviamente, poiché kInfinity è const.

+1

Nota: l'inizializzazione di un const statico richiede un costruttore predefinito fornito dall'utente. Il sistema predefinito non lo taglierà. Lo menziono solo perché la classe pubblicata dall'OP non * ne ha uno. (e +1 btw). – WhozCraig

6
  1. Non che io sappia, anche se mi sembra che si sta utilizzando riferimenti a Inf e oggetti reali in un disordinato modo nei tuoi sovraccarichi.

    Normalmente, si prendono argomenti in base al valore o const di riferimento e si restituiscono in base al valore per tutti gli operatori oltre a quelli di assegnazione composti (in cui si restituisce per riferimento) per ottenere la semantica prevista. Naturalmente, poiché il tuo oggetto Inf non ha uno stato, tutto ha senso solo fino a un certo punto.

  2. Vorrei utilizzare uno const globale per evitare le parentesi e la chiamata di funzione potenziale coinvolti in un singleton. Se questo è anche static non dovrebbe fare quasi nessuna differenza (non si sta accedendo a this in alcun modo).

  3. Devi scrivere il proprio operatore come una funzione libera:

    inline Inf operator+(long int i, const Inf&) { return *this;} 
    
+0

+1. E si noti che l'OP potrebbe coprire un * lotto * più basi di un semplice "lungo" se è stato utilizzato un set di funzioni libere gestito da SFINAE. Bella risposta. – WhozCraig

0

Ognuno è stato veramente d'aiuto nel guidarmi verso la Vera Via. Per aiutare gli altri che sono venuti alla ricerca di risposte, piuttosto che farti ricucire la risposta insieme dall'intero thread, ho pensato di pubblicare ciò che ho finito. I commenti che suggeriscono miglioramenti sono benvenuti, ovviamente.

#ifndef MU_INDEFINITE_H 
#define MU_INDEFINITE_H 

namespace mu { 

    class Indefinite { 
    public: 

    static const Indefinite kIndefinite; 

    Indefinite() {} 
    ~Indefinite() {} 

    }; 

    inline Indefinite operator+ (long int i, Indefinite t) { return Indefinite::kIndefinite; } 
    inline Indefinite operator+ (Indefinite t, long int i) { return Indefinite::kIndefinite; } 
    inline Indefinite operator+ (Indefinite t1, Indefinite t2) { return Indefinite::kIndefinite; } 

    inline Indefinite operator- (long int i, Indefinite t) { return Indefinite::kIndefinite; } 
    inline Indefinite operator- (Indefinite t, long int i) { return Indefinite::kIndefinite; } 
    inline Indefinite operator- (Indefinite t1, Indefinite t2) { return Indefinite::kIndefinite; } 

    inline Indefinite operator* (long int i, Indefinite t) { return Indefinite::kIndefinite; } 
    inline Indefinite operator* (Indefinite t, long int i) { return Indefinite::kIndefinite; } 
    inline Indefinite operator* (Indefinite t1, Indefinite t2) { return Indefinite::kIndefinite; } 

    // It's not clear what i/Indefinite should produce. Forbid it for now. 
    // inline long int operator/ (long int i, Indefinite t) { return 0; } 
    inline Indefinite operator/ (Indefinite t, long int i) { return Indefinite::kIndefinite; } 
    inline Indefinite operator/ (Indefinite t1, Indefinite t2) { return Indefinite::kIndefinite; } 

    inline bool operator> (long int i, Indefinite t) { return false; } 
    inline bool operator> (Indefinite t, long int i) { return true; } 
    inline bool operator> (Indefinite t1, Indefinite t2) { return false; } 

    inline bool operator>= (long int i, Indefinite t) { return false; } 
    inline bool operator>= (Indefinite t, long int i) { return true; } 
    inline bool operator>= (Indefinite t1, Indefinite t2) { return true; } 

    inline bool operator< (long int i, Indefinite t) { return true; } 
    inline bool operator< (Indefinite t, long int i) { return false; } 
    inline bool operator< (Indefinite t1, Indefinite t2) { return false; } 

    inline bool operator<= (long int i, Indefinite t) { return true; } 
    inline bool operator<= (Indefinite t, long int i) { return false; } 
    inline bool operator<= (Indefinite t1, Indefinite t2) { return true; } 

    inline bool operator== (long int i, Indefinite t) { return false; } 
    inline bool operator== (Indefinite t, long int i) { return false; } 
    inline bool operator== (Indefinite t1, Indefinite t2) { return true; } 

    inline bool operator!= (long int i, Indefinite t) { return true; } 
    inline bool operator!= (Indefinite t, long int i) { return true; } 
    inline bool operator!= (Indefinite t1, Indefinite t2) { return false; } 

} 

#endif 
Problemi correlati