Domanda

Ho una piccola domanda: come faccio a sapere che tipo di C ++ puntatore è

Io uso spesso una piccola funzione nei miei programmi di console per raccogliere l'input, che sembra qualcosa di simile:

void query(string what-to-ask, [insert datatype here] * input)

Vorrei creare una forma generica, utilizzando un puntatore nullo, ma non riesco a cin un puntatore nullo, così come faccio a sapere il suo tipo così posso lanciarla?

È stato utile?

Soluzione

E 'passato molto tempo dall'ultima volta che ho scritto in C ++, ma ...

Non puoi usare un Template ?

Altri suggerimenti

Non è possibile.

Tuttavia, un'alternativa è quella di farla finita con puntatori void, rendere tutto derivare da una classe base comune e utilizzare RTTI.

Un esempio:

class Base
{
public:
   virtual ~Base() {}
};

class Foo : public Base { /* ... */ };

void SomeFunction(Base *obj)
{
    Foo *p = dynamic_cast<Foo*>(obj);
    if (p)
    {
        // This is of type Foo, do something with it...
    }
}

Invece di passare un void* in giro che è quindi necessario lanciare al tipo corretto, probabilmente si dovrebbe usare una funzione di modello che può essere utilizzato con tutti i tipi che si desidera leggere.

In questo modo si ottiene il codice type-safe e non c'è bisogno di modo per scrivere codice speciale per la maggior parte dei tipi di ingresso:

template<typename T>
void query(const string &whattoask, T &input) {
  cout << whattoask << endl;
  cin >> input;
  cout << endl;
}

int main() {
  int i;
  double d;
  string s;

  query("An integer: ", i);
  query("Floating point: ", d);
  query("A word: ", s);
}

void* è la forma tutti i dati hanno. Non si può "determinare" esso - è di esso, tutti i dati che avete in programma di sono void*! Sì, sono pezzi grezzi della memoria, in base alla progettazione.

potrebbe intero programma il codice con l'utilizzo di soli void*. Per fortuna, il linguaggio C fornisce ulteriori convenienza a te, che ti permette di manipolare alcuni dati, come è che non sono stati void*. Ma se avete intenzione di usare questo vantaggio, non si dovrebbe lanciare loro di void* e dimenticare che tipo fossero.

La tua domanda non è affatto chiaro per me, ma forse ciò che si vuole è quello di sovraccaricare query

void query(string what2ask, int* input) {
   cout << what2ask;
   cin >> *input;
}


void query(string what2ask, float* input) {
   cout << what2ask;
   cin >> *input;
}

int age;
float sqrt2;
query("How old are you?", &age);
query("What's the square root of 2?", &sqrt2);

Se ho capito quello che stai chiedendo poi la solita modo per farlo è quello di creare una classe di interfaccia che supporta query(string what-to-ask) e poi invece di utilizzare un puntatore nullo solo passare un puntatore all'interfaccia. Poi si può chiamare query () su tale istanza.

No. Non si può fare questo. Se avete bisogno di qualcosa come questo, suggerisco Boost.Any .

Se si controlla il tipo di dati da soli, probabilmente fare una classe / struct che contiene un enum di tutti i tipi di dati che ti interessano e passare tale. È quindi possibile interrogare il passato in puntatore per il suo tipo di dati, e poi gettato in modo appropriato.

IE (codice di allarme pseudo -. Trattare questo come una struct per ora)

class MyDataType {
     enum aDataType type;
     void * myData;
}

void query( string whatToAsk, MyDataType * pdata)
{
    switch ( pdata.type) {
        case integer:
              int * workInt = (int * )  pdata;
              do whatever you want to to get the data
              break;
        case someFunkyObject:
              someFunkyObject pob = (SomeFunkyObject *) pdata;
              Do whatever you want with the data.

        etc.
    }
}

Si potrebbe leggere come un char * e poi analizzare la stringa (char da char) per determinare se si tratta di un int, float, string, qualsiasi cosa. La parte difficile è la conversione di esso.

Ad esempio:

per ogni carattere nella stringa

if (personaggio è un '')

++ decimalcount

else if (carattere è una lettera)

++ lettercount

fine ciclo

se decimalcount> 0 && lettercount == 0   analizzare attraverso ciascuna cifra da destra a sinistra, moltiplicando per potenze di 10 e aggiungendo la somma

altrimenti se decimalcount == 1 && lettercount == 0

imparare galleggianti sono rappresentati in formato binario e trovano la funzione di qualcun altro per convertirlo per voi

altrimenti se lettercount> 0

è una stringa. yay!

per quanto possibile, evitare di puntatori void, utilizzare i modelli. Sto cercando di recente una base di codice enorme con un sacco di * vuoto, è molto in termini di tempo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top