Design per ritorno di tipo multiplo

1

Sto lavorando in C ++ e ho questo problema.

class Container {
   Container(int which_type_to_use_a_b_or_c);

   A & getData(A & prototype);
   B & getData(B & prototype);
   C & getData(C & prototype);

private:
   A a;
   B b;
   C c;
   int type_used;

}

Solo uno dei tipi di dati A, B o C viene effettivamente utilizzato in una classe di istanza Container. La bandierina del costruttore decide quale usare. Quando è il momento di ottenere un riferimento all'oggetto interno, ho bisogno di una routine getData che restituisca il riferimento del diverso tipo. Per disambiguare, passo un "prototipo" A () B () o C ().

Non mi piace molto questo schema, ma non riesco a trovare nulla di meglio a causa della mia tavolozza limitata in c ++. Avete altri approcci disponibili? tieni presente che il contenitore dei modelli su A, B o C non è un'opzione a causa di altri vincoli.

    
posta Stefano Borini 10.04.2013 - 10:41
fonte

3 risposte

8

Potresti utilizzare un'unione discriminata, come Boost.Variant

class Container {
    typedef boost::variant<A,B,C> ABC;
    enum Type { UseA, UseB, UseC };

    explicit Container(Type t);

    ABC & getData();

private:
    ABC value;
}

ma francamente sembra un problema X-Y . Cosa stai cercando di realizzare?

NB. hai detto in un commento

... we also can't use pointers, only references

potresti essere interessato a sapere che il polimorfismo di runtime funziona semplicemente bene con riferimenti (anche se non aiuta qui).

    
risposta data 10.04.2013 - 11:06
fonte
3

Sembra molto simile a Boost.Variant che potrebbe sostituire la tua classe o aiutarti a implementarla facilmente.

Fondamentalmente fornisce un modo per allocare memoria che può contenere A, B, C che sono definiti in fase di compilazione. Quando hai bisogno di ottenere i dati, è facile recuperare quello che vuoi. Puoi controllare in modo dinamico quale ora è memorizzata e se il codice utente già sa quale tipo dovrebbe essere disponibile, può solo estrarre il valore e ottenere un'eccezione se non è il tipo previsto.

    
risposta data 10.04.2013 - 11:00
fonte
2

oltre al concetto di Boost :: Variant o semplici unioni, questo è un problema che può essere risolto meglio usando un modello. (e so che non vuoi usare i template, ma se non vuoi dirci perché, risponderò comunque - potrebbe aiutare qualcun altro nuovo a C ++ a ottenere la risposta giusta)

Quindi dovresti creare una classe in cui il tipo che stai contenendo non viene passato come flag, ma viene passato come 'istruzione del compilatore' per generare una classe specifica per il tipo che desideri utilizzare.

ad es.

template <class T>
class Container{
    T the_type_thats_used;
  public:
    T & getData(T & prototype);
    typedef T type_used;
};

questo è ciò per cui i template sono usati, un buon esempio è l'STL che ha un carico di classi contenitore che funzionano in questo modo.

    
risposta data 10.04.2013 - 11:30
fonte

Leggi altre domande sui tag