Saiba Tipo de ponteiro void C ++
-
19-09-2019 - |
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?
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.