关键词:定义指向子类的基类指针
绑定:将函数调用跟它的地址关联起来的过程。
void test_bind(Base* pb) {
00652010 55 push ebp
00652011 8B EC mov ebp,esp
00652013 81 EC CC 00 00 00 sub esp,0CCh
00652019 53 push ebx
0065201A 56 push esi
0065201B 57 push edi
0065201C 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
00652022 B9 33 00 00 00 mov ecx,33h
00652027 B8 CC CC CC CC mov eax,0CCCCCCCCh
0065202C F3 AB rep stos dword ptr es:[edi]
0065202E B9 27 10 66 00 mov ecx,offset _E9DE5D9E_虚函数与多态\虚函数与多态\虚函数与多态@cpp (0661027h)
00652033 E8 3D F3 FF FF call @__CheckForDebuggerJustMyCode@4 (0651375h)
int a = pb->x;
00652038 8B 45 08 mov eax,dword ptr [pb]
0065203B 8B 48 04 mov ecx,dword ptr [eax+4] ;保存的是父类的变量x的值
0065203E 89 4D F8 mov dword ptr [a],ecx
printf("a=%d\n", a);
00652041 8B 45 F8 mov eax,dword ptr [a]
00652044 50 push eax
00652045 68 48 CB 65 00 push offset string "a=%d\n" (065CB48h)
0065204A E8 0B F0 FF FF call _printf (065105Ah)
0065204F 83 C4 08 add esp,8
pb->Function_1(); ;Function_1函数是普通函数,直接绑定
00652052 8B 4D 08 mov ecx,dword ptr [pb]
00652055 E8 18 F6 FF FF call Base::Function_1 (0651672h)
pb->Function_2(); ;Function_2函数是虚函数, 根据传进来的实际指针类型进行运行时的动态绑定
0065205A 8B 45 08 mov eax,dword ptr [pb]
0065205D 8B 10 mov edx,dword ptr [eax]
0065205F 8B F4 mov esi,esp
00652061 8B 4D 08 mov ecx,dword ptr [pb]
00652064 8B 02 mov eax,dword ptr [edx]
00652066 FF D0 call eax
00652068 3B F4 cmp esi,esp
0065206A E8 1F F3 FF FF call __RTC_CheckEsp (065138Eh)
}
#include <iostream>
#include <stdio.h>
using namespace std;
class Base {
public :
int x;
public:
Base() {
x = 100;
}
void Function_1() {
printf("base1:func1...\n");
}
virtual void Function_2() {
printf("base1:func2...virtual\n");
}
};
class Sub : public Base {
public:
int x;
Sub() {
x = 200;
}
void Function_1() {
printf("Sub:func1...\n");
}
virtual void Function_2() {
printf("Sub:func2...virtual\n");
}
};
void test_bind(Base* pb) {
int a = pb->x;
printf("a=%d\n", a);
pb->Function_1();
pb->Function_2();
}
//定义一个函数指针
typedef void(*pFunction)(void);
int main()
{
Sub pb;
test_bind(&pb);
return 0;
}
对于普通的成员和成员函数,指向子类的基类指针,
多态如何实现
当基类没有定义虚函数时,指向子类的基类指针永远不会执行子类的函数,
#include <iostream>
#include <stdio.h>
using namespace std;
class Base {
public :
int x;
int y;
public:
Base() {
x = 1;
y = 2;
}
void print() {
printf("Base x=%x,y=%x\n",x,y);
}
};
class Sub1 : public Base {
public:
int A;
Sub1() {
x = 4;
y = 5;
A = 6;
}
void print() {
printf("Sub1 x=%x,y=%x,A=%x\n", x, y,A);
}
};
class Sub2 : public Base {
public:
int A;
Sub2() {
x = 7;
y = 8;
A = 9;
}
void print() {
printf("Sub2 x=%x,y=%x,A=%x\n", x, y, A);
}
};
void test_bind() {
Base b;
Sub1 s1;
Sub2 s2;
Base* arry[] = { &b,&s1,&s2 };
for (int i = 0; i < 3; i++) {
arry[i]->print();
}
}
int main()
{
test_bind();
return 0;
}
- 执行结果
Base x=1,y=2
Base x=4,y=5
Base x=7,y=8
当基类有定义虚函数时,子类重写了这个函数(即使没有定义成虚函数)指向子类的基类指针会执行子类的函数.
#include <iostream>
#include <stdio.h>
using namespace std;
struct Base {
public :
int x;
int y;
public:
Base() {
x = 1;
y = 2;
}
virtual void print() {
printf("Base x=%x,y=%x\n",x,y);
}
};
struct Sub1 : public Base {
public:
int A;
Sub1() {
x = 4;
y = 5;
A = 6;
}
virtual void print() {
printf("Sub1 x=%x,y=%x,A=%x\n", x, y,A);
}
};
class Sub2 : public Base {
public:
int A;
Sub2() {
x = 7;
y = 8;
A = 9;
}
virtual void print() {
printf("Sub2 x=%x,y=%x,A=%x\n", x, y, A);
}
};
void test_bind() {
Base b;
Sub1 s1;
Sub2 s2;
Base* arry[] = { &b,&s1,&s2 };
for (int i = 0; i < 3; i++) {
arry[i]->print();
}
}
//定义一个函数指针
int main()
{
test_bind();
return 0;
}
- 执行结果:
Base x=1,y=2
Sub1 x=4,y=5,A=6
Sub2 x=7,y=8,A=9
网友评论