C++ detailed resolution of Pointers to class member functions

  • 2020-04-02 01:28:40
  • OfStack

First, a function pointer is a pointer to a set of functions of the same type. Similarly, we can think of a class member function as a pointer to a member function of the same type in the same class. The former is a direct reference to the address of the function, while the latter is literally related to classes and objects.

Function pointer instance:


typedef int (*p)(int,int);//Defines a function pointer type that accepts two ints and returns an int variable
int func(int x,int y)
{
 printf("func:x=%d,y=%d/n",x,y);
 return (x<y?x:y);
}
int main()
{
 p fun=func;//Define a function pointer and assign a function pointer to it
 cout<<"min:"<<(*fun)(4,5)<<endl;//Why does *fun need to be expanded with ()? Because * has a lower precedence than (), it becomes *(fun() without ().
 return 0;
}
    Pointers to class member functions have one more class distinction: 
class A
{
public:
 int func(int x,int y)
 {
  printf("A::func:x=%d,y=%d/n",x,y);
  return (x<y?x:y);
 }
};
typedef int (A::*p)(int,int);//The pointer name must be qualified with the class name A:: of the type to which it belongs
int main()
{
 p fun=&A::func;
 A a;                  //Because the dereferenced address of a member function must be attached to the address of an object, we must create an object.
 cout<<"min:"<<(a.*fun)(4,5)<<endl;
 return 0;
}

Hey.. Just for use.*   It feels weird.

Next we can expand a bit:

#include <tchar.h>
#include <iostream>
#include <stdio.h>
using namespace std;
class A
{
public:
 int func1(int x,int y)
 {
  printf("A::func:x=%d,y=%d/n",x,y);
  return (x<y?x:y);
 }
 virtual int func2(int x,int y)
 {
  printf("A::func:x=%d,y=%d/n",x,y);
  return (x>y?x:y);
 }
};
class B:public A
{
public:
 virtual int func2(int x,int y)
 {
  printf("B::func:x=%d,y=%d/n",x,y);
  return (x+y);
 }
};
typedef int (A::*p)(int,int);//The pointer name must be qualified with the class name A:: of the type to which it belongs
typedef int (B::*p0)(int,int);
int main()
{
 A a;                   //Because the dereferenced address of a member function must be attached to the address of an object, we must create an object.

 p fun=&A::func1;
 cout<<(a.*fun)(4,5)<<endl;
 cout<<(b.*fun)(4,5)<<endl<<endl;
 fun=&A::func2;
 cout<<(a.*fun)(4,5)<<endl;//Notice that this is a virtual function, and it's amazing that class member function Pointers support polymorphism.
 cout<<(b.*fun)(4,5)<<endl<<endl;
 //fun=&B::func2;         // This style error drops because there is no derived class " A pointer to a class member function " To the base class " A pointer to a class member function " Implicit conversion 
 fun=(int (A::*)(int,int))&B::func2;//It should be cast
 cout<<(a.*fun)(4,5)<<endl; 
 cout<<(b.*fun)(4,5)<<endl<<endl;

 p0 fun0=&B::func2;
 cout<<(a.*fun)(4,5)<<endl;
 cout<<(b.*fun)(4,5)<<endl<<endl;

 fun0=&A::func2;           //Right, because we're implicitly converting here
 cout<<(a.*fun)(4,5)<<endl;
 cout<<(b.*fun)(4,5)<<endl<<endl;
 //From the above, we can easily find that the relationship between pointer base class and derived class pointing to class member function is completely opposite to that between pointer base class and derived class pointing to class object.
 //The layout of a base class member function is considered a subset of the layout of a derived class member function
 return 0;
}

take   Is the use of class member function Pointers for template classes
Examples are as follows:

#include <tchar.h>
#include <iostream>
#include <stdio.h>
using namespace std;
class A
{
public:
 int func(int x,int y)
 {
  printf("A::func : x=%d,y=%d/n",x,y);
  return (x<y?x:y);
 }
};
class B
{
public:
 int func(int x,int y)
 {
  printf("B::func : x=%d,y=%d/n",x,y);
  return (x>y?x:y);
 }
};
template<class T>
class C
{
public:
 T c;
 void Print()
 {
  int (T::*p)(int,int)=&T::func;
  (c.*p)(4,5);
 }
};
int main()
{
 C<A> ca;
 C<B> cb;
 ca.Print();
 cb.Print();
 return 0;
}

You can see it very clearly from above. In fact, it is no different from the ordinary template. Only the qualified name should be the parameter wine OK...
Hey hey...


Related articles: