Pergunta

Eu tenho uma pequena pergunta: como faço para descobrir o que digite um C ++ ponteiro é

?

Costumo usar uma pequena função em meus programas de console para reunir entrada, que é algo como isto:

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

Eu gostaria de criar uma forma genérica, usando um ponteiro nulo, mas eu não posso cin um ponteiro nulo, assim como eu descobrir seu tipo para que eu possa lançá-lo?

Foi útil?

Solução

Tem sido um longo tempo desde a última vez que eu codificado em C ++, mas ...

Você não pode usar um Template ?

Outras dicas

Você não pode.

No entanto, uma alternativa é para acabar com ponteiros void, faça tudo o que deriva de uma classe base comum e usar RTTI.

Um exemplo:

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...
    }
}

Em vez de passar um void* torno de que você precisa então de elenco para o tipo correto você provavelmente deve usar uma função de modelo que pode ser usado com todos os tipos que você quer ler.

Desta forma, você obter o código de tipo seguro e não têm a maneira de escrever código especial para a maioria dos tipos de entrada:

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* é a forma todas dados têm. Você não pode "determinar"-lo - é isso, todos os dados que você tem no programa são void*! Sim, eles são pedaços crus de memória, por design.

Você poderia programa de todo o seu código com o uso de apenas void*. Felizmente, a linguagem C fornece adicional conveniência para você, permitindo-lhe manipular alguns dados, como é que eles não eram void*. Mas se você estiver indo para usar esta conveniência, você não deve lançá-los para void* e esquecer que tipo eram.

A sua questão não é de todo claro para mim, mas talvez o que você quer é a sobrecarga 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 eu entendo o que você está pedindo, em seguida, a maneira usual de fazer isso é criar uma classe de interface que suporta query(string what-to-ask) e, em seguida, em vez de usar um ponteiro nulo apenas passar um ponteiro para a interface. Em seguida, você pode chamar query () nessa instância.

Não. Você não pode fazer isso. Se você precisa de algo como isso, sugiro Boost.Any .

Se você controlar o tipo de dados a si mesmo, eu provavelmente iria fazer uma classe / struct que contém uma enumeração de todos os tipos de dados que lhe interessam e passar essa. Você poderia, então, consultar o passado em ponteiro para ele do tipo de dados, e então lançou de forma adequada.

IE (aviso de código pseudo -. Tratar isso como um struct por agora)

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.
    }
}

Você pode lê-lo como um char * e, em seguida, analisar a cadeia (char por caractere) para determinar se ele é um int, float, string, qualquer que seja. A parte difícil é convertê-lo.

Por exemplo:

para cada personagem na seqüência

if (personagem é um '')

++ decimalcount

else if (personagem é uma carta)

++ lettercount

final para o laço

Se decimalcount> 0 && lettercount == 0 analisar através de cada dígito da direita para a esquerda, multiplicando por potências de 10 e adicionando a soma

else if decimalcount == 1 && lettercount == 0

aprender como flutuadores são representados em binário e encontrar a função de outra pessoa para convertê-lo para você

else if lettercount> 0

é uma string. yay!

Sempre que possível, evite ponteiros void, modelos de uso. Eu estou olhando recentemente uma base de código enorme com muito void *, é muito demorado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top