Quote Originally Posted by TheGreatCthulhu View Post
And I really wanted to understand all this; so, I downloaded C++/CLI specification from here (although I suspect that I already have in some obscure folder, as it might have installed with VS).
Wow! I had no idea there might be something like a C++/CLI standard. I always somehow presumed it was an MS homegrown thing. However, the document on that ECMA page is only about 15% the size (in bytes) of the N3126 C++0x standard draft I have here. Does it only specify the differences between standard C++ and C++/CLI?

Which means that what you highlighted uses the pointer-to-member-function syntax. (For non-member or static function, the '&' is optional, for member functions it is required.)
Yes after some thinking I see no other option than a pointer-to-member-function too. I remember once having read something about the C++/CLI syntax for these pointers but couldn't find it again. I'm relatively sure it uses the * to designate a pointer unlike the usual C++/CLI habits. (And I think it actually is a pointer rather than a tracking handle because member functions of course are not stored in the GC heap.) I came to the conclusion that the type signature of the parameter I highlighted some posts back must at least be something similar to void (Component::*)(Object ^, MouseEventArgs ^).

While the use of * above looks justified, I think it is arguable when explicitly specifying dereferenciation of a tracking handle like in this snippet from a form load handler:

Code:
  Object ^objTemp = config["windowLocation"];
  if (objTemp) {
    Point pnt = *dynamic_cast<Point ^>(objTemp);
    if (pnt != Point(-1, -1)) Location = pnt;
  }
I probably might have been able to write that more elegant using implicit unboxing but this is from one of my real apps and one of those working things I didn't change (yet).

The fact that the MulticastDelegate constructor to which you referred in post #11 takes an Object ^ along with a string holding the name of the method to call reminds me to the use of Type::InvokeMember() like in some sample code I wrote or a combination of Type::GetMethod() and MethodInfo::Invoke() I used in a module used in as of now two of my apps. Both ways of method invocation essentially take a pointer to the object to refer to (which may/must be nullptr if the method is either static, global or namespace-scope) and a string holding the name of the method to call. I have used both ways to call a late-bound method just once yet and can't decide which one actually is more convenient, more efficient or preferable for other reasons.

In native C++, a regular function pointer and a pointer-to-member have different internal representation (as pointed out here) - I'm guessing that it's similar in C++/CLI, and that this internal data structure is somehow mapped to what the CLR expects.
Your guess is probably right. As I already pointed out above, function pointers in C++/CLI probably need to be actual pointers while the this reference to the object the pointer is bound to needs to be a tracking handle. So in C++/CLI a pointer-to-member-function seems to be some kind of hybrid thing.

BTW, this was really exciting, because while digging I've discovered something that I wasn't aware of; the thing is, native C++ pointers to member functions support polymorphism, so if the inheriting class overrides the base member, the derived implementation gets called. It made me wonder if the same goes for delegates in .NET, and my first quick tests indicate that it does! I had no idea!
Fascinating! I always thought of a pointer-to-member-function (in native C++) as a mere bundle of a pointer to the function code and a this pointer. I didn't have an idea either that they can do such fancy things. Now that I know of it it seems just logical, though. I never had a need for that yet (and an extremely rare need for pointers-to-member-functions at all except for creation of .NET delegates) but I feel the probability is high that sometime the day will come when it's good to know that...

[...] Anyway, I wouldn't call them "helper types", as these directly support .NET infrastructure - these are at the very core of the .NET type system.
Ok, I must admit I terribly underrated them. They actually implement the vast majority of functionality of the typed that implicitly are derived from them and thus are of invaluable importance despite the fact that "normal" developers will never have to deal with them directly. Compiler developers, however, are likely to actually do that relatively frequently.

I was talking both native C++ and C++/CLI, but honestly, I had native C++ in mind. Don't get me wrong: I'm not questioning C++ as a language - I'm just saying that C++ is not "hardcore" OO - as opposed to languages on the other extreme, like Smalltalk (where even classes are objects, whose class is Metaclass... o_O). [...] OOP principles are really good design principles, but as you yourself noted, practical considerations (including the current evolutionary state of software and hardware) sometimes dictate that things need to be done differently in certain aspects.
Oh, yes, ok... I often tend to forget about that. Although I was talking about the "pure doctrine" of encapsulation (I think that was in this very thread here) I ignored the fact that C++ itself is by no means a "pure doctrine" laguage. Probably this is mostly due to the two facts that C++ was my first encounter with OO and that I do practically all my OO-related work in C++ (well, and C++/CLI in the last few months).

I know that Smalltalk often is referred to as the flagship among the OO languages, but I think there have been some languages catching up during the last years, didn't they (whatever they are - can't think of any particular one right now)?

If language syntax is the this interface used by developers (clients) to communicate to the compiler, then I might have some dissatisfaction with it.
To be honest, I don't understand the sentence above. Is the word "this" in it in some way related to the this pointer (in C++) or handle (in C++/CLI)?

For example, native C++ provides delete, and delete[] - this has probably been pain for anyone learning C++. But, really, why is such a distinction needed? From the perspective of the developer (client) - who cares?! Why not just one keyword - internally, the compiler could transform it to whatever it wants.
Ok, now you really just made me doubting something I was accepting as a standing fact during the past years... (1) Initially I was wondering myself why there's a need for two distinct variants of delete. (2) I then sometime came to the conclusion that the need for the distinction is based on the fact that the destructor only needs to be called once for a single object and more than once for an array (for non-POD types only, of course). Can't the runtime determine whether it's an array of objects or a single object (or an array comprising just a single object) from the size of a single object and the size of the memory block to be released? But what if the underlying OS can't provide the information on the size of the memory block (for some really weird reason)? (3) - and that's what just came to my mind right now: If the OS really shouldn't be able to provide the information about the size of the memory block, then how is the runtime supposed to determine for how many array elements to call the destructor in case of a delete []?

Then, take the function pointers and pointers to member functions. There is a difference, sure, internal representations are different, but again - why do I need to know this?
I can't really come up with the syntax to call a member function via a pointer-to-member-function but wouldn't simplifying the calling syntax too much severely obscure the actual meaning of the statement? Yes, the pointer-to-member-function (in its simplest form) holds both the pointer to the object as well as to the function so there's no information needed besides the pointer and the parameters to pass. But applying maximum simplification would make the call via the pointer look like a direct call to a member function in the scope of the class the call is made from (hmmm, is there really no more compact term for that? ) or a global function (ignoring namespace-scope functions here that I consider to be globals anyway).

Or take the C++ style casting operators.
I haven't made my peace with them yet either but I think I won't condemn them before I positively know they're not justified.