Question

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's type so I can cast it?

Was it helpful?

Solution

It's been a long time since the last time I coded in C++, but...

Can't you use a Template?

OTHER TIPS

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

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

You could read it in as a char * and then parse the string (char by char) to determine if it is an int, float, string, whatever. The tricky part is converting it.

For example:

for each character in string

if (character is a '.')

++decimalcount

else if (character is a letter)

++lettercount

end for loop

if decimalcount > 0 && lettercount == 0 parse through each digit from right to left, multiplying by powers of 10 and adding the sum

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

learn how floats are represented in binary and find someone else's function to convert it for you

else if lettercount > 0

it's a string. yay!

wherever possible, avoid void pointers, use templates. I am recently looking a huge code base with plenty of void *, it is very time consuming.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top