I have a small question: how do I find out what type a C++ pointer is?
I often use a small function in my console programs to gather input, which looks something like this:
void query(string what-to-ask, [insert datatype here] * input)
I would like to create a generic form, using a void pointer, but I can't cin a void pointer, so how to I find out it开发者_StackOverflow's type so I can cast it?
You can't.
However, one alternative is to do away with void pointers, make everything derive from a common base class and use RTTI.
An example:
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...
}
}
Instead of passing a void*
around that you then need to cast to the correct type you should probably use a template function that can be used with all types you want to read.
This way you get type-safe code and don't have to way to write special code for most input types:
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*
is the form all data have. You can't "determine" it -- it is it, any data you have in program are void*
! Yes, they are raw chunks of memory, by design.
You could program whole your code with use of void*
only. Luckily, C language provides additional convenience to you, letting you manipulate some data as is they were not void*
. But if you're going to use this convenience, you should not cast them to void*
and forget about what type they were.
Your question is not at all clear to me, but perhaps what you want is to overload 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);
If you control the datatype yourself, I would probably make a class/struct that contains an enum of all of the data types you care about and pass that. You could then query the passed in pointer for it's datatype, and then cast appropriately.
IE ( pseudo code warning - treating this as a struct for now. )
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.
}
}
If I understand what you're asking then the usual way to do this is to create an interface class that supports query(string what-to-ask)
and then instead of using a void pointer just pass a pointer to the interface. Then you can call query() on that instance.
Nope. You can't do this. If you need something like this, I suggest Boost.Any.
精彩评论