protected关键字:
摘自MSDN
protected 关键字指定对 member-list 中的成员直到下一个访问说明符(public 或 private)或类定义的末尾的访问。 只能通过以下项使用声明为 protected 的类成员:
最初声明这些成员的类的成员函数。
最初声明这些成员的类的友元。
使用公共或受保护访问(派生自最初声明这些成员的类)派生的类。
也对受保护成员具有专用访问权限的以私有方式派生的直接类。
当以基类的名称开头时,protected 关键字指定基类的公共成员和保护成员是其派生类的保护成员。
保护成员不像 private 成员那样专用,private 成员仅对从中声明它们的类的成员可访问,但保护成员也不像 public 成员那样公开,public 成员在任何函数中均可访问。
也声明为 static 的保护成员对派生类的任何友元或成员函数均可访问。 也声明为 static 的保护成员对派生类中的友元或成员函数可访问,但只能通过指向派生类的指针、对派生类的引用或派生类的对象。
#include
using namespace std;
class Base {
public:
Base(int j): i(j) {}
virtual~Base() {}
// virtual
void func1() {
i *= 10;
func2(); //此处调用子类
}
int getValue() {
return i;
}
protected:
virtual void func2() {
i++;
}
protected:
int i;
};
class Child: public Base {
public:
Child(int j): Base(j) {}
void func1() {
i *= 100;
func2();
}
protected:
void func2() {
i += 2;
}
};
int main() {
Base * pb = new Child(1);
pb->func1();//此处的this指针并未改变 只有一个对象
cout << pb->getValue() << endl;
delete pb;
}
输出: 12
下面是反汇编代码
1: #include
2: using namespace std;
3:
4: class Base {
5: public:
6: Base(int j): i(j) {}
00401800 push ebp
00401801 mov ebp,esp
00401803 sub esp,44h
00401806 push ebx
00401807 push esi
00401808 push edi
00401809 push ecx
0040180A lea edi,[ebp-44h]
0040180D mov ecx,11h
00401812 mov eax,0CCCCCCCCh
00401817 rep stos dword ptr [edi]
00401819 pop ecx
0040181A mov dword ptr [ebp-4],ecx
0040181D mov eax,dword ptr [ebp-4]
00401820 mov ecx,dword ptr [ebp+8]
00401823 mov dword ptr [eax+4],ecx
00401826 mov edx,dword ptr [ebp-4]
00401829 mov dword ptr [edx],offset Base::`vftable' (0046e028)
0040182F mov eax,dword ptr [ebp-4]
00401832 pop edi
00401833 pop esi
00401834 pop ebx
00401835 mov esp,ebp
00401837 pop ebp
00401838 ret 4
7: virtual~Base() {}
00401900 push ebp
00401901 mov ebp,esp
00401903 sub esp,44h
00401906 push ebx
00401907 push esi
00401908 push edi
00401909 push ecx
0040190A lea edi,[ebp-44h]
0040190D mov ecx,11h
00401912 mov eax,0CCCCCCCCh
00401917 rep stos dword ptr [edi]
00401919 pop ecx
0040191A mov dword ptr [ebp-4],ecx
0040191D mov eax,dword ptr [ebp-4]
00401920 mov dword ptr [eax],offset Base::`vftable' (0046e028)
00401926 pop edi
00401927 pop esi
00401928 pop ebx
00401929 mov esp,ebp
0040192B pop ebp
0040192C ret
8: void func1() {
004016F0 push ebp
004016F1 mov ebp,esp
004016F3 sub esp,44h
004016F6 push ebx
004016F7 push esi
004016F8 push edi
004016F9 push ecx
004016FA lea edi,[ebp-44h]
004016FD mov ecx,11h
00401702 mov eax,0CCCCCCCCh
00401707 rep stos dword ptr [edi]
00401709 pop ecx
0040170A mov dword ptr [ebp-4],ecx //this
9: i *= 10;
0040170D mov eax,dword ptr [ebp-4]
00401710 mov ecx,dword ptr [eax+4]
00401713 imul ecx,ecx,0Ah
00401716 mov edx,dword ptr [ebp-4]
00401719 mov dword ptr [edx+4],ecx
10: func2();
0040171C mov eax,dword ptr [ebp-4]
0040171F mov edx,dword ptr [eax]
00401721 mov esi,esp
00401723 mov ecx,dword ptr [ebp-4] //this
00401726 call dword ptr [edx+4]
00401729 cmp esi,esp
0040172B call __chkesp (00420e90)
11: }
00401730 pop edi
00401731 pop esi
00401732 pop ebx
00401733 add esp,44h
00401736 cmp ebp,esp
00401738 call __chkesp (00420e90)
0040173D mov esp,ebp
0040173F pop ebp
00401740 ret
12: int getValue() {
00401760 push ebp
00401761 mov ebp,esp
00401763 sub esp,44h
00401766 push ebx
00401767 push esi
00401768 push edi
00401769 push ecx
0040176A lea edi,[ebp-44h]
0040176D mov ecx,11h
00401772 mov eax,0CCCCCCCCh
00401777 rep stos dword ptr [edi]
00401779 pop ecx
0040177A mov dword ptr [ebp-4],ecx
13: return i;
0040177D mov eax,dword ptr [ebp-4]
00401780 mov eax,dword ptr [eax+4]
14: }
00401783 pop edi
00401784 pop esi
00401785 pop ebx
00401786 mov esp,ebp
00401788 pop ebp
00401789 ret
15: protected:
16: virtual void func2() {
00401850 push ebp
00401851 mov ebp,esp
00401853 sub esp,44h
00401856 push ebx
00401857 push esi
00401858 push edi
00401859 push ecx
0040185A lea edi,[ebp-44h]
0040185D mov ecx,11h
00401862 mov eax,0CCCCCCCCh
00401867 rep stos dword ptr [edi]
00401869 pop ecx
0040186A mov dword ptr [ebp-4],ecx
17: i++;
0040186D mov eax,dword ptr [ebp-4]
00401870 mov ecx,dword ptr [eax+4]
00401873 add ecx,1
00401876 mov edx,dword ptr [ebp-4]
00401879 mov dword ptr [edx+4],ecx
18: }
0040187C pop edi
0040187D pop esi
0040187E pop ebx
0040187F mov esp,ebp
00401881 pop ebp
00401882 ret
19: protected:
20: int i;
21: };
22: class Child: public Base {
23: public:
24: Child(int j): Base(j) {}
004017A0 push ebp
004017A1 mov ebp,esp
004017A3 sub esp,44h
004017A6 push ebx
004017A7 push esi
004017A8 push edi
004017A9 push ecx
004017AA lea edi,[ebp-44h]
004017AD mov ecx,11h
004017B2 mov eax,0CCCCCCCCh
004017B7 rep stos dword ptr [edi]
004017B9 pop ecx
004017BA mov dword ptr [ebp-4],ecx
004017BD mov eax,dword ptr [ebp+8]
004017C0 push eax
004017C1 mov ecx,dword ptr [ebp-4]
004017C4 call @ILT+35(Base::Base) (00401028)
004017C9 mov ecx,dword ptr [ebp-4]
004017CC mov dword ptr [ecx],offset Child::`vftable' (0046e01c)
004017D2 mov eax,dword ptr [ebp-4]
004017D5 pop edi
004017D6 pop esi
004017D7 pop ebx
004017D8 add esp,44h
004017DB cmp ebp,esp
004017DD call __chkesp (00420e90)
004017E2 mov esp,ebp
004017E4 pop ebp
004017E5 ret 4
25: void func1() {
26: i *= 100;
27: func2();
28: }
29: protected:
30: void func2() {
00401940 push ebp
00401941 mov ebp,esp
00401943 sub esp,44h
00401946 push ebx
00401947 push esi
00401948 push edi
00401949 push ecx
0040194A lea edi,[ebp-44h]
0040194D mov ecx,11h
00401952 mov eax,0CCCCCCCCh
00401957 rep stos dword ptr [edi]
00401959 pop ecx
0040195A mov dword ptr [ebp-4],ecx
31: i += 2;
0040195D mov eax,dword ptr [ebp-4]
00401960 mov ecx,dword ptr [eax+4]
00401963 add ecx,2
00401966 mov edx,dword ptr [ebp-4]
00401969 mov dword ptr [edx+4],ecx
32: }
0040196C pop edi
0040196D pop esi
0040196E pop ebx
0040196F mov esp,ebp
00401971 pop ebp
00401972 ret
33: };
34: int main() {
004015D0 push ebp
004015D1 mov ebp,esp
004015D3 push 0FFh
004015D5 push offset __ehhandler$_main (00447c4b)
004015DA mov eax,fs:[00000000]
004015E0 push eax
004015E1 mov dword ptr fs:[0],esp
004015E8 sub esp,5Ch
004015EB push ebx
004015EC push esi
004015ED push edi
004015EE lea edi,[ebp-68h]
004015F1 mov ecx,17h
004015F6 mov eax,0CCCCCCCCh
004015FB rep stos dword ptr [edi]
35: Base * pb = new Child(1);
004015FD push 8
004015FF call operator new (004209a0)
00401604 add esp,4
00401607 mov dword ptr [ebp-18h],eax
0040160A mov dword ptr [ebp-4],0
00401611 cmp dword ptr [ebp-18h],0
00401615 je main+56h (00401626)
00401617 push 1
00401619 mov ecx,dword ptr [ebp-18h]
0040161C call @ILT+405(Child::Child) (0040119a)
00401621 mov dword ptr [ebp-24h],eax eax == ecx
00401624 jmp main+5Dh (0040162d)
00401626 mov dword ptr [ebp-24h],0
0040162D mov eax,dword ptr [ebp-24h]
00401630 mov dword ptr [ebp-14h],eax
00401633 mov dword ptr [ebp-4],0FFFFFFFFh
0040163A mov ecx,dword ptr [ebp-14h]
0040163D mov dword ptr [ebp-10h],ecx this
36: pb->func1();
00401640 mov ecx,dword ptr [ebp-10h]
00401643 call @ILT+160(Base::func1) (004010a5) this
37: cout << pb->getValue() << endl;
00401648 push offset @ILT+220(std::endl) (004010e1)
0040164D mov ecx,dword ptr [ebp-10h]
00401650 call @ILT+575(Base::getValue) (00401244)
00401655 push eax
00401656 mov ecx,offset std::cout (0047be90)
0040165B call @ILT+280(std::basic_ostream >::operator<<) (0040111d)
00401660 mov ecx,eax
00401662 call @ILT+515(std::basic_ostream >::operator<<) (00401208)
38: delete pb;
00401667 mov edx,dword ptr [ebp-10h]
0040166A mov dword ptr [ebp-20h],edx
0040166D mov eax,dword ptr [ebp-20h]
00401670 mov dword ptr [ebp-1Ch],eax
00401673 cmp dword ptr [ebp-1Ch],0
00401677 je main+0C3h (00401693)
00401679 mov esi,esp
0040167B push 1
0040167D mov ecx,dword ptr [ebp-1Ch]
00401680 mov edx,dword ptr [ecx]
00401682 mov ecx,dword ptr [ebp-1Ch]
00401685 call dword ptr [edx]
00401687 cmp esi,esp
00401689 call __chkesp (00420e90)
0040168E mov dword ptr [ebp-28h],eax
00401691 jmp main+0CAh (0040169a)
00401693 mov dword ptr [ebp-28h],0
39: }
0040169A mov ecx,dword ptr [ebp-0Ch]
0040169D mov dword ptr fs:[0],ecx
004016A4 pop edi
004016A5 pop esi
004016A6 pop ebx
004016A7 add esp,68h
004016AA cmp ebp,esp
004016AC call __chkesp (00420e90)
004016B1 mov esp,ebp
004016B3 pop ebp
004016B4 ret
@ILT+160(?func1@Base@@QAEXXZ):
004010A5 jmp Base::func1 (004016f0)
@ILT+130(??1Base@@UAE@XZ):
00401087 jmp Base::~Base (00401900)
@ILT+55(?func2@Child@@MAEXXZ):
0040103C jmp Child::func2 (00401940)
@ILT+35(??0Base@@QAE@H@Z):
00401028 jmp Base::Base (00401800)
@ILT+40(?func2@Base@@MAEXXZ):
0040102D jmp Base::func2 (00401850)
@ILT+130(??1Base@@UAE@XZ):
00401087 jmp Base::~Base (00401900)
@ILT+405(??0Child@@QAE@H@Z):
0040119A jmp Child::Child (004017a0)
@ILT+575(?getValue@Base@@QAEHXZ):
00401244 jmp Base::getValue (00401760)
@ILT+585(_main):
0040124E jmp main (004015d0)
@ILT+610(??_EChild@@UAEPAXI@Z):
00401267 jmp Child::`scalar deleting destructor' (00401980)
@ILT+615(??_EBase@@UAEPAXI@Z):
0040126C jmp Base::`scalar deleting destructor' (00401890)
@ILT+660(??1Child@@UAE@XZ):
00401299 jmp Child::~Child (004019f0)
@ILT+575(?getValue@Base@@QAEHXZ):
00401244 jmp Base::getValue (00401760)
@ILT+585(_main):
0040124E jmp main (004015d0)
@ILT+575(?func1@Child@@UAEXXZ):
00401244 jmp Child::func1 (00401960)
Child::`scalar deleting destructor':
00401980 push ebp
00401981 mov ebp,esp
00401983 sub esp,44h
00401986 push ebx
00401987 push esi
00401988 push edi
00401989 push ecx
0040198A lea edi,[ebp-44h]
0040198D mov ecx,11h
00401992 mov eax,0CCCCCCCCh
00401997 rep stos dword ptr [edi]
00401999 pop ecx
0040199A mov dword ptr [ebp-4],ecx
0040199D mov ecx,dword ptr [ebp-4]
004019A0 call @ILT+660(Child::~Child) (00401299)
004019A5 mov eax,dword ptr [ebp+8]
004019A8 and eax,1
004019AB test eax,eax
004019AD je Child::`scalar deleting destructor'+3Bh (004019bb)
004019AF mov ecx,dword ptr [ebp-4]
004019B2 push ecx
004019B3 call operator delete (00406d20)
004019B8 add esp,4
004019BB mov eax,dword ptr [ebp-4]
004019BE pop edi
004019BF pop esi
004019C0 pop ebx
004019C1 add esp,44h
004019C4 cmp ebp,esp
004019C6 call __chkesp (00420e90)
004019CB mov esp,ebp
004019CD pop ebp
004019CE ret 4
Base::`scalar deleting destructor':
00401890 push ebp
00401891 mov ebp,esp
00401893 sub esp,44h
00401896 push ebx
00401897 push esi
00401898 push edi
00401899 push ecx
0040189A lea edi,[ebp-44h]
0040189D mov ecx,11h
004018A2 mov eax,0CCCCCCCCh
004018A7 rep stos dword ptr [edi]
004018A9 pop ecx
004018AA mov dword ptr [ebp-4],ecx
004018AD mov ecx,dword ptr [ebp-4]
004018B0 call @ILT+130(Base::~Base) (00401087)
004018B5 mov eax,dword ptr [ebp+8]
004018B8 and eax,1
004018BB test eax,eax
004018BD je Base::`scalar deleting destructor'+3Bh (004018cb)
004018BF mov ecx,dword ptr [ebp-4]
004018C2 push ecx
004018C3 call operator delete (00406d20)
004018C8 add esp,4
004018CB mov eax,dword ptr [ebp-4]
004018CE pop edi
004018CF pop esi
004018D0 pop ebx
004018D1 add esp,44h
004018D4 cmp ebp,esp
004018D6 call __chkesp (00420e90)
004018DB mov esp,ebp
004018DD pop ebp
004018DE ret 4
Child::`scalar deleting destructor':
00401980 push ebp
00401981 mov ebp,esp
00401983 sub esp,44h
00401986 push ebx
00401987 push esi
00401988 push edi
00401989 push ecx
0040198A lea edi,[ebp-44h]
0040198D mov ecx,11h
00401992 mov eax,0CCCCCCCCh
00401997 rep stos dword ptr [edi]
00401999 pop ecx
0040199A mov dword ptr [ebp-4],ecx
0040199D mov ecx,dword ptr [ebp-4]
004019A0 call @ILT+660(Child::~Child) (00401299)
004019A5 mov eax,dword ptr [ebp+8]
004019A8 and eax,1
004019AB test eax,eax
004019AD je Child::`scalar deleting destructor'+3Bh (004019bb)
004019AF mov ecx,dword ptr [ebp-4]
004019B2 push ecx
004019B3 call operator delete (00406d20)
004019B8 add esp,4
004019BB mov eax,dword ptr [ebp-4]
004019BE pop edi
004019BF pop esi
004019C0 pop ebx
004019C1 add esp,44h
004019C4 cmp ebp,esp
004019C6 call __chkesp (00420e90)
004019CB mov esp,ebp
004019CD pop ebp
004019CE ret 4
Child::~Child:
004019F0 push ebp
004019F1 mov ebp,esp
004019F3 sub esp,44h
004019F6 push ebx
004019F7 push esi
004019F8 push edi
004019F9 push ecx
004019FA lea edi,[ebp-44h]
004019FD mov ecx,11h
00401A02 mov eax,0CCCCCCCCh
00401A07 rep stos dword ptr [edi]
00401A09 pop ecx
00401A0A mov dword ptr [ebp-4],ecx
00401A0D mov ecx,dword ptr [ebp-4]
00401A10 call @ILT+130(Base::~Base) (00401087)
00401A15 pop edi
00401A16 pop esi
00401A17 pop ebx
00401A18 add esp,44h
00401A1B cmp ebp,esp
00401A1D call __chkesp (00420e90)
00401A22 mov esp,ebp
00401A24 pop ebp
00401A25 ret
若是改成 虚函数func1()
36: pb->func1();
00401650 mov edx,dword ptr [ebp-10h]
00401653 mov eax,dword ptr [edx]
00401655 mov esi,esp
00401657 mov ecx,dword ptr [ebp-10h]
0040165A call dword ptr [eax+4]