user90450
user90450

Reputation: 127

C++ syntax question

What does the following syntax mean?

typedef void* hMyClass; //typedef as a handle or reference
hMyClass f = &something;
const MyClass& foo = static_cast<MyClass&>(*f);
foo.bar();

Upvotes: 0

Views: 947

Answers (5)

Alan
Alan

Reputation: 46813

void* is commonly used for a generic pointer.

In C# it would be similar to something like:

object o = new XmlDocument();

object o = new List();

However, in C++, there is very little type safety being enforced. IIRC, static_cast is the same as (cast), in that no run-time type checks are made.

Upvotes: 0

David Gladfelter
David Gladfelter

Reputation: 4213

It's hard to say exactly what this "means" without more context. I presume you're working on someone else's code and the lines you're showing appear scattered across a number of functions.

My best guess as to the code intent is that this is a mechanism to deal with 3rd-party code/libraries. It is common in C++ to use (non-templated) 3rd-party libraries with your own types. If those libraries need to temporarily hold data that you created and own, you need a way to give the library access to your data even though the library doesn't know about your types. One example is a callback/event feature. If a library will asynchronously notify you when an event occurs, you need to give it a function pointer and also user-defined data so that when the function is called, you know what to do with it. Libraries commonly take a void* pointer for this user-supplied data. It is common in C++ to just pass in an object instance for the user-supplied data and then delegate to that object to handle the callback. Here's what the code would look like:

// 3rd-party library API
typedef void (*PingNotifyPtr)(void*);
void NotifyOnPing(PingNotifyPtr, void* userData);
// User Code
void MyNotify(void* myData)
{
   MyClass* ptr = (MyClass*)myData;
   // do something with ptr
}
void Main()
{
   MyClass *pClass = new MyClass();
   NotifyOnPing(&MyNotify, pClass);
   // the callback is now armed with all the data it needs.
}

Many libraries accomplish this by declaring "void*" arguments. This is a raw pointer to some memory location. Anything could be at that location, an integer, a class instance, a string, etc. The 3rd-party library holds onto that pointer and returns it back to your code at some point.

The 3rd line of your example code is taking the void* pointer and casting it to a reference to a class instance. C++ references are like pointers except they cannot be NULL and they use value syntax (using the '.' operator instead of the '->' operator, for example.) The 4th line of your example code then uses a method on the re-constituted class instance.

Anyway, if all 4 lines of code are consecutive in the code base you're dealing with, that code means that someone's ignorant of C++. Here's a more compact way to do the same code in one line:

((const MyClass*)something)->Foo();

or, if you prefer value syntax:

(*((const MyClass*)something)).Foo();

Good Luck!

Upvotes: 0

tpdi
tpdi

Reputation: 35141

Essentially, somebody has stored an MyClass pointer in a void pointer, likely passing it to callback. This code, having presumably been called back, is casting it back, to use it as a MyClass.

Also, it has syntax errors, as eagerwishes notes.

Upvotes: 0

user90052
user90052

Reputation: 2686

This actually isn't valid. You're assigning a value to a type, not a variable on line 2.

Upvotes: 1

Uri
Uri

Reputation: 89739

A static_cast means that the system does not actually try to make sure that when you are converting from one reference type to another, the thing you are converting is actually an instance of the target type (unlike dynamic casts).

Hence, you are telling the compiler that you are smart enough to know that the address which is contained in hMyClass and which came from something actually contains an instance of MyClass, and that you are taking full responsibility for the unpredictable things that will happen if you are wrong.

What is the type of your "something"? You could also have an error there. You may want a &something.

Upvotes: 2

Related Questions