<p>In C++, can member function pointers be used to point to derived (or even base) class members? </p>

<p>EDIT: 
Perhaps an example will help. Suppose we have a hierarchy of three classes <code>X</code>, <code>Y</code>, <code>Z</code> in order of inheritance. 
<code>Y</code> therefore has a base class <code>X</code> and a derived class <code>Z</code>.</p>

<p>Now we can define a member function pointer <code>p</code> for class <code>Y</code>. This is written as:</p>

<pre><code>void (Y::*p)();
</code></pre>

<p>(For simplicity, I'll assume we're only interested in functions with the signature <code>void f()</code> )  </p>

<p>This pointer <code>p</code> can now be used to point to member functions of class <code>Y</code>.</p>

<p>This question (two questions, really) is then:</p>

<ol>
<li>Can <code>p</code> be used to point to a function in the derived class <code>Z</code>?</li>
<li>Can <code>p</code> be used to point to a function in the base class <code>X</code>?</li>
</ol>

[{'answer_id': 60010, 'author': 'Steve Duitsman', 'author_id': 4575, 'author_profile': 'https://Stackoverflow.com/users/4575', 'pm_score': 1, 'selected': False, 'text': '<p>I believe so.  Since the function pointer uses the signature to identify itself, the base/derived behavior would rely on whatever object you called it on.</p>\n'}, {'answer_id': 60016, 'author': 'dagorym', 'author_id': 171, 'author_profile': 'https://Stackoverflow.com/users/171', 'pm_score': 2, 'selected': False, 'text': '<p>You might want to check out this article <a href="http://www.codeproject.com/KB/cpp/FastDelegate.aspx" rel="nofollow noreferrer">Member Function Pointers and the Fastest Possible C++ Delegates</a>  The short answer seems to be yes, in some cases.</p>\n'}, {'answer_id': 60023, 'author': 'Matt Price', 'author_id': 852, 'author_profile': 'https://Stackoverflow.com/users/852', 'pm_score': 4, 'selected': False, 'text': '<p>I\'m not 100% sure what you are asking, but here is an example that works with virtual functions:</p>\n\n<pre><code>#include &lt;iostream&gt;\nusing namespace std;\n\nclass A { \npublic:\n    virtual void foo() { cout &lt;&lt; "A::foo\\n"; }\n};\nclass B : public A {\npublic:\n    virtual void foo() { cout &lt;&lt; "B::foo\\n"; }\n};\n\nint main()\n{\n    void (A::*bar)() = &amp;A::foo;\n    (A().*bar)();\n    (B().*bar)();\n    return 0;\n}\n</code></pre>\n'}, {'answer_id': 1130707, 'author': 'smh', 'author_id': 1077, 'author_profile': 'https://Stackoverflow.com/users/1077', 'pm_score': 1, 'selected': False, 'text': '<p>My experimentation revealed the following: Warning - this might be undefined behaviour. It would be helpful if someone could provide a definitive reference.</p>\n\n<ol>\n<li>This worked, but required a cast when assigning the derived member function to <code>p</code>.</li>\n<li>This also worked, but required extra casts when dereferencing <code>p</code>.</li>\n</ol>\n\n<p>If we\'re feeling really ambitious we could ask if <code>p</code> can be used to point to member functions of unrelated classes. I didn\'t try it, but the <a href="http://www.codeproject.com/KB/cpp/FastDelegate.aspx" rel="nofollow noreferrer">FastDelegate</a> page linked in dagorym\'s answer suggests it\'s possible.</p>\n\n<p>In conclusion, I\'ll try to avoid using member function pointers in this way. Passages like the following don\'t inspire confidence:</p>\n\n<blockquote>\n  <p>Casting between member function\n  pointers is an extremely murky area.\n  During the standardization of C++,\n  there was a lot of discussion about\n  whether you should be able to cast a\n  member function pointer from one class\n  to a member function pointer of a base\n  or derived class, and whether you\n  could cast between unrelated classes.\n  By the time the standards committee\n  made up their mind, different compiler\n  vendors had already made\n  implementation decisions which had\n  locked them into different answers to\n  these questions. [<a href="http://www.codeproject.com/KB/cpp/FastDelegate.aspx" rel="nofollow noreferrer">FastDelegate article</a>]</p>\n</blockquote>\n'}, {'answer_id': 2688154, 'author': 'Winston Ewert', 'author_id': 322806, 'author_profile': 'https://Stackoverflow.com/users/322806', 'pm_score': 1, 'selected': False, 'text': '<p>Assume that we have <code>class X, class Y : public X, and class Z : public Y</code></p>\n\n<p>You should be able to assign methods for both X, Y to pointers of type void (Y::*p)() but not methods for Z. To see why consider the following:</p>\n\n<pre><code>void (Y::*p)() = &amp;Z::func; // we pretend this is legal\nY * y = new Y; // clearly legal\n(y-&gt;*p)(); // okay, follows the rules, but what would this mean?\n</code></pre>\n\n<p>By allowing that assignment we permit the invocation of a method for Z on a Y object which could lead to who knows what. You can make it all work by casting the pointers but that is not safe or guaranteed to work.</p>\n'}, {'answer_id': 2688631, 'author': 'outis', 'author_id': 90527, 'author_profile': 'https://Stackoverflow.com/users/90527', 'pm_score': 6, 'selected': True, 'text': '<p>C++03 std, <a href="http://www.open-std.org/jtc1/sc22/WG21/docs/wp/html/nov97-2/conv.html#conv.mem" rel="noreferrer">§4.11 2 Pointer to member conversions</a>:</p>\n\n<blockquote>\n  <p>An rvalue of type “pointer to member of B of type <i>cv</i> T,” where B is a class type, can be converted to an rvalue of type “pointer to member of D of type <i>cv</i> T,” where D is a derived class (clause 10) of B. If B is an inaccessible (clause 11), ambiguous (10.2) or virtual (10.1) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion refers to the same member as the pointer to member before the conversion took place, but it refers to the base class member as if it were a member of the derived class. The result refers to the member in D’s instance of B. Since the result has type “pointer to member of D of type <i>cv</i> T,” it can be dereferenced with a D object. The result is the same as if the pointer to member of B were dereferenced with the B sub-object of D.   The null member pointer value is converted to the null member pointer value of the destination type. <sup>52)</sup></p>\n  \n  <p><sup>52)</sup>The rule for conversion of pointers to members (from pointer to member of base to pointer to member of derived) appears inverted compared to the rule for pointers to objects (from pointer to derived to pointer to base) (4.10, clause 10). This inversion is necessary to ensure type safety. Note that a pointer to member is not a pointer to object or a pointer to function and the rules for conversions of such pointers do not apply to pointers to members. In particular, a pointer to member cannot be converted to a void*.</p>\n</blockquote>\n\n<p>In short, you can convert a pointer to a member of an accessible, non-virtual base class to a pointer to a member of a derived class as long as the member isn\'t ambiguous. </p>\n\n<pre><code>class A {\npublic: \n    void foo();\n};\nclass B : public A {};\nclass C {\npublic:\n    void bar();\n};\nclass D {\npublic:\n    void baz();\n};\nclass E : public A, public B, private C, public virtual D {\npublic: \n    typedef void (E::*member)();\n};\nclass F:public E {\npublic:\n    void bam();\n};\n...\nint main() {\n   E::member mbr;\n   mbr = &amp;A::foo; // invalid: ambiguous; E\'s A or B\'s A?\n   mbr = &amp;C::bar; // invalid: C is private \n   mbr = &amp;D::baz; // invalid: D is virtual\n   mbr = &amp;F::bam; // invalid: conversion isn\'t defined by the standard\n   ...\n</code></pre>\n\n<p>Conversion in the other direction (via <code>static_cast</code>) is governed by <a href="http://www.open-std.org/jtc1/sc22/WG21/docs/wp/html/nov97-2/expr.html#expr.static.cast" rel="noreferrer">§ 5.2.9</a> 9:</p>\n\n<blockquote>\n  <p>An rvalue of type "pointer to member of D of type <i>cv1</i> T" can be converted to an rvalue of type "pointer to member of B of type <i>cv2</i> T", where B is a base class (clause <a href="http://www.open-std.org/jtc1/sc22/WG21/docs/wp/html/nov97-2/derived.html#class.derived" rel="noreferrer">10 class.derived</a>) of D, if a valid standard conversion from "pointer to member of B of type T" to "pointer to member of D of type T" exists (<a href="http://www.open-std.org/jtc1/sc22/WG21/docs/wp/html/nov97-2/conv.html#conv.mem" rel="noreferrer">4.11 conv.mem</a>), and <i>cv2</i> is the same cv-qualification as, or greater cv-qualification than, <i>cv1</i>.<sup>11)</sup> The null member pointer value (<a href="http://www.open-std.org/jtc1/sc22/WG21/docs/wp/html/nov97-2/conv.html#conv.mem" rel="noreferrer">4.11 conv.mem</a>) is converted to the null member pointer value of the destination type. If class B contains the original member, or is a base or derived class of the class containing the original member, the resulting pointer to member points to the original member.  Otherwise, the result of the cast is undefined. [Note: although class B need not contain the original member, the dynamic type of the object on which the pointer to member is dereferenced must contain the original member; see <a href="http://www.open-std.org/jtc1/sc22/WG21/docs/wp/html/nov97-2/expr.html#expr.mptr.oper" rel="noreferrer">5.5 expr.mptr.oper</a>.]</p>\n  \n  <p><sup>11)</sup> Function types (including those used in pointer to member function\n    types) are never cv-qualified; see <a href="http://www.open-std.org/jtc1/sc22/WG21/docs/wp/html/nov97-2/decl.html#dcl.fct" rel="noreferrer">8.3.5 dcl.fct</a>.</p>\n</blockquote>\n\n<p>In short, you can convert from a derived <code>D::*</code> to a base <code>B::*</code> if you can convert from a <code>B::*</code> to a <code>D::*</code>, though you can only use the <code>B::*</code> on objects that are of type D or are descended from D.</p>\n'}, {'answer_id': 2688793, 'author': 'CB Bailey', 'author_id': 19563, 'author_profile': 'https://Stackoverflow.com/users/19563', 'pm_score': 3, 'selected': False, 'text': "<p>The critical issue with pointers to members is that they can be applied to any reference or pointer to a class of the correct type. This means that because <code>Z</code> is derived from <code>Y</code> a pointer (or reference) of type pointer (or reference) to <code>Y</code> may actually point (or refer) to the base class sub-object of <code>Z</code> or <em>any other class</em> derived from <code>Y</code>.</p>\n\n<pre><code>void (Y::*p)() = &amp;Z::z_fn; // illegal\n</code></pre>\n\n<p>This means that anything assigned to a pointer to member of <code>Y</code> must actually work with any <code>Y</code>. If it was allowed to point to a member of <code>Z</code> (that wasn't a member of <code>Y</code>) then it would be possible to call a member function of <code>Z</code> on some thing that wasn't actually a <code>Z</code>.</p>\n\n<p>On the other hand, any pointer to member of <code>Y</code> also points the member of <code>Z</code> (inheritance means that <code>Z</code> has all the attributes and methods of its base) is it is legal to convert a pointer to member of <code>Y</code> to a pointer to member of <code>Z</code>. This is inherently safe.</p>\n\n<pre><code>void (Y::*p)() = &amp;Y::y_fn;\nvoid (Z::*q)() = p; // legal and safe\n</code></pre>\n"}, {'answer_id': 28506633, 'author': 'Gena Batsyan', 'author_id': 1427063, 'author_profile': 'https://Stackoverflow.com/users/1427063', 'pm_score': 0, 'selected': False, 'text': '<p>Here is an example of what works.\nYou can override a method in derived class, and another method of base class that uses pointer to this overridden method indeed calls the derived class\'s method.</p>\n\n<pre><code>#include &lt;iostream&gt;\n#include &lt;string&gt;\n\nusing namespace std;\n\nclass A {\npublic:\n    virtual void traverse(string arg) {\n        find(&amp;A::visit, arg);\n    }\n\nprotected:\n    virtual void find(void (A::*method)(string arg),  string arg) {\n        (this-&gt;*method)(arg);\n    }\n\n    virtual void visit(string arg) {\n        cout &lt;&lt; "A::visit, arg:" &lt;&lt; arg &lt;&lt; endl;\n    }\n};\n\nclass B : public A {\nprotected:\n    virtual void visit(string arg) {\n        cout &lt;&lt; "B::visit, arg:" &lt;&lt; arg &lt;&lt; endl;\n    }\n};\n\nint main()\n{\n    A a;\n    B b;\n    a.traverse("one");\n    b.traverse("two");\n    return 0;\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/60000', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1077/']