protected关键字:
摘自MSDN
protected 关键字指定对 member-list 中的成员直到下一个访问说明符(public 或 private)或类定义的末尾的访问。 只能通过以下项使用声明为 protected 的类成员:
-
最初声明这些成员的类的成员函数。
-
最初声明这些成员的类的友元。
-
使用公共或受保护访问(派生自最初声明这些成员的类)派生的类。
-
也对受保护成员具有专用访问权限的以私有方式派生的直接类。
当以基类的名称开头时,protected 关键字指定基类的公共成员和保护成员是其派生类的保护成员。
保护成员不像 private 成员那样专用,private 成员仅对从中声明它们的类的成员可访问,但保护成员也不像 public 成员那样公开,public 成员在任何函数中均可访问。
也声明为 static 的保护成员对派生类的任何友元或成员函数均可访问。 也声明为 static 的保护成员对派生类中的友元或成员函数可访问,但只能通过指向派生类的指针、对派生类的引用或派生类的对象。
private:只能由1.该类中的函数、2.其友元函数访问。
不能被任何其他访问,该类的对象也不能访问。
protected:可以被1.该类中的函数、2.子类的函数、以及3.其友元函数访问。
但不能被该类的对象访问。
public:可以被1.该类中的函数、2.子类的函数、3.其友元函数访问,也可以由4.该类的对象访问。
下面分析一个例子
#include <iostream>
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 <iostream>
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: virt