// CTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <wtypes.h>
using namespace std;
int fun1(char arg1)
{
cout<<arg1<<endl;
return 1;
}
void funWithArgFun1(char arg1, int(*pFun)(char))
{
pFun(arg1);
}
class A
{
public:
int i1;
virtual int func1(int i)
{
++i;
++i;
cout << i << endl;
return i;
}
virtual int func2(int i)
{
return i;
}
};
class B
{
public:
int i1;
virtual int func1(int i)
{
cout << ++i << endl;
return i;
}
virtual int func2(int i)
{
return i;
}
};
class C : public A
{
public:
virtual int func1(int i)
{
--i;
--i;
cout << i << endl;
return i;
}
};
template<class T>
void TestClassMemberFunction(T* pObj, int (T::*pFunction)(int) )
{
int i = 0;
(pObj->*pFunction)(i);
}
int _tmain(int argc, _TCHAR* argv[])
{
funWithArgFun1('h', fun1);
int (A::*fp1)(int);
int A::*ip1;
fp1 = &A::func1;
ip1 = &A::i1;
// A* oba
// oba.*ip1 = 2;
// (oba.*fp1)(oba.*ip1);
A* oba = new A;
TestClassMemberFunction<A>(oba, &A::func1);
B* objb = new B;
TestClassMemberFunction(objb, &B::func1);
C* objCExtendA = new C;
TestClassMemberFunction((A*)objCExtendA, &A::func1);
delete oba;
oba = NULL;
delete objb;
objb = NULL;
delete objCExtendA;
objCExtendA = NULL;
return 0;
}
关键点是:
1. 在使用对象函数指针的地址计算是通过 “对象指针” + “函数的偏移量” 来获取对象的函数地址的
2. 即使第三个调用的时候使用 A::func1和强制转换,但是由于虚函数指针的原因&A::func1其实是&C::func1,所以可以断定这里对象的多态性还是起作用的,结果调用的还是C类的func1
3. 使用template<class T> 来提高函数的通用性