views:

184

answers:

2

I've just found some C++ code (at http://msdn.microsoft.com/en-us/library/k8336763%28VS.71%29.aspx), which uses a technique I've never seen before to add types to an existing class:

class Testpm {
public:
   void m_func1() { cout << "m_func1\n"; }
   int m_num;
};

// Define derived types pmfn and pmd.
// These types are pointers to members m_func1() and m_num, respectively.
void (Testpm::*pmfn)() = &Testpm::m_func1;
int Testpm::*pmd = &Testpm::m_num;

int main() {
   Testpm ATestpm;
   Testpm *pTestpm = new Testpm;

   // Access the member function
   (ATestpm.*pmfn)();
   (pTestpm->*pmfn)();   // Parentheses required since * binds

   // Access the member data
   ATestpm.*pmd = 1;
   pTestpm->*pmd = 2;

   cout  << ATestpm.*pmd << endl
         << pTestpm->*pmd << endl;
}

Can someone please tell me what this technique for defining derived types is called, or point me to some documentation on it? I've never come across it in 13 years of using C++, and would like to end my ignorance.

+4  A: 

I don't think they're "adding types" to the class. They seem to be just defining types of pointers to member functions and member data of the class, and then using those to access the member function and data member. Similar to how you'd declare types to non-member functions, but being members of the class the syntax differs.

From this site here

Regarding their syntax, there are two different types of function pointers: On the one hand there are pointers to ordinary C functions or to static C++ member functions. On the other hand there are pointers to non-static C++ member functions. The basic difference is that all pointers to non-static member functions need a hidden argument: The this-pointer to an instance of the class. Always keep in mind: These two types of function pointers are incompatible with each other.

pxb
In fact they're not even defining types of pointers - they're defining the pointers themselves.
Paul Baker
I stand corrected, they're not defining types to the pointers, just creating instances of them and using them. I blame a lack of sleep...
pxb
+6  A: 

The comment is incorrect: pmfn and pmd are not "derived types" at all (they are not even types!). They are pointers to members.

Paul Baker
hard to believe, but true: even pointers to members are types.
sbi
"Are types", or "have types"? If I wrote typedef int Testpm::*pmd_t = pmd_t pmd; clearly pmd_t is a type, but do you mean pmd is a type also? The second case applies to the code in the question.
Paul Baker
Looks like they put `typedef`, and then removed it and forgot to change the comment. In fact, what is called "compound type" in C++ is called "derived type" in C, thus the comment in the code, i believe.
Johannes Schaub - litb