首先明白以下两点:
1、类的一个特征就是封装,public和private作用就是实现这一目的。
即:用户代码(类外)可以访问public成员而不能访问private成员;private成员只能由类成员(类内)和友元访问。
2、类的另一个特征就是继承,protected的作用就是实现这一目的。
即:protected成员可以被派生类对象访问,不能被用户代码(类外)访问。其既解决了private成员不能被派生类访问的劣势,又保留了private成员不能被类外访问的特点。
现来看看如下示例:
1 /* 2 @author:CodingMengmeng 3 @theme:深入理解C++中public、protected及private用法 4 @time:2017-2-23 15:59:10 5 @blog:http://www.cnblogs.com/codingmengmeng/ 6 */ 7 #include<iostream> 8 #include<assert.h> 9 using namespace std; 10 class A{ 11 public: 12 int a; 13 A(){ 14 a1 = 1; 15 a2 = 2; 16 a3 = 3; 17 a = 4; 18 } 19 void fun(){ 20 cout << a << endl; //正确 21 cout << a1 << endl; //正确 22 cout << a2 << endl; //正确,类内访问 23 cout << a3 << endl; //正确,类内访问 24 } 25 public: 26 int a1; 27 protected: 28 int a2; 29 private: 30 int a3; 31 }; 32 int main(){ 33 A itema; 34 itema.a = 10; //正确 35 itema.a1 = 20; //正确 36 itema.a2 = 30; //错误,类外不能访问protected成员 37 itema.a3 = 40; //错误,类外不能访问private成员 38 system("pause"); 39 return 0; 40 }
运行结果:
继承中的特点:
先记住:不管继不继承,上面的规则永远适用!
有public,protected,private三种继承方式,它们相应地改变了基类成员的访问属性。
1、public继承:基类public成员,protected成员,private成员的访问属性在派生类中分别变成:public, protected, private
2、protected继承:基类的public成员,protected成员,private成员的访问属性在派生类中分别变成:protected, protected, private
3、private继承:基类public成员,protected成员,private成员的访问属性在派生类中分别变成:private, private, private
但无论哪种继承方式,上面两点都没有改变:
1.private成员只能被本类成员(类内)和友元访问,不能被派生类访问;
2.protected成员可以被派生类访问。
再来看看一下代码:
1、public继承
1 /* 2 @author:CodingMengmeng 3 @theme:深入理解C++中public、protected及private用法 4 @time:2017-2-23 16:09:53 5 @blog:http://www.cnblogs.com/codingmengmeng/ 6 */ 7 8 //1、public继承 9 #include <iostream> 10 #include <assert.h> 11 using namespace std; 12 13 class A{ 14 public: 15 int a; 16 A(){ 17 a1 = 1; 18 a2 = 2; 19 a3 = 3; 20 a = 4; 21 } 22 void fun(){ 23 cout << a << endl;//right 24 cout << a1 << endl;//right 25 cout << a2 << endl;//right 26 cout << a3 << endl;//right 27 } 28 public: 29 int a1; 30 protected: 31 int a2; 32 private: 33 int a3; 34 }; 35 36 class B : public A{ 37 public: 38 int a; 39 B(int i){ 40 A(); 41 a = i; 42 } 43 void fun(){ 44 cout << a << endl;//正确,public成员 45 cout << a1 << endl;//正确,基类的public成员,在派生类中仍是public成员。 46 cout << a2 << endl;//正确,基类的protected成员,在派生类中仍是protected可以被派生类中被类内访问。 47 cout << a3 << endl;//错误,基类的private成员不能被派生类访问。 48 } 49 }; 50 51 int main() 52 { 53 B b(10); 54 cout << b.a << endl; 55 cout << b.a1 << endl; //正确 56 cout << b.a2 << endl; //错误,类外不能访问protected成员 57 cout << b.a3 << endl; //错误,类外不能访问private成员 58 system("pause"); 59 return 0; 60 }
2、protected继承
1 /* 2 @author:CodingMengmeng 3 @theme:深入理解C++中public、protected及private用法 4 @time:2017-2-23 16:20:23 5 @blog:http://www.cnblogs.com/codingmengmeng/ 6 */ 7 //2、protected继承 8 #include<iostream> 9 #include<assert.h> 10 using namespace std; 11 class A{ 12 public: 13 int a; 14 A(){ 15 a1 = 1; 16 a2 = 2; 17 a3 = 3; 18 a = 4; 19 } 20 void fun(){ 21 cout << a << endl; //right 22 cout << a1 << endl; //right 23 cout << a2 << endl; //right 24 cout << a3 << endl; //right 25 } 26 public: 27 int a1; 28 protected: 29 int a2; 30 private: 31 int a3; 32 }; 33 class B : protected A{ 34 public: 35 int a; 36 B(int i){ 37 A(); 38 a = i; 39 } 40 void fun(){ 41 cout << a << endl; //正确,public成员。 42 cout << a1 << endl; //正确,基类的public成员,在派生类中变成了protected,可以被派生类类内访问。 43 cout << a2 << endl; //正确,基类的protected成员,在派生类中还是protected,可以被派生类类内访问。 44 cout << a3 << endl; //错误,基类的private成员不能被派生类访问。 45 } 46 }; 47 int main(){ 48 B b(10); 49 cout << b.a << endl; //正确。public成员 50 cout << b.a1 << endl; //错误,protected成员不能在类外访问。 51 cout << b.a2 << endl; //错误,protected成员不能在类外访问。 52 cout << b.a3 << endl; //错误,private成员不能在类外访问。 53 system("pause"); 54 return 0; 55 }
3、private继承
1 /* 2 @author:CodingMengmeng 3 @theme:深入理解C++中public、protected及private用法 4 @time:2017-2-23 16:23:08 5 @blog:http://www.cnblogs.com/codingmengmeng/ 6 */ 7 //3、private继承 8 #include<iostream> 9 #include<assert.h> 10 using namespace std; 11 class A{ 12 public: 13 int a; 14 A(){ 15 a1 = 1; 16 a2 = 2; 17 a3 = 3; 18 a = 4; 19 } 20 void fun(){ 21 cout << a << endl; //right 22 cout << a1 << endl; //right 23 cout << a2 << endl; //right 24 cout << a3 << endl; //right 25 } 26 public: 27 int a1; 28 protected: 29 int a2; 30 private: 31 int a3; 32 }; 33 class B : private A{ 34 public: 35 int a; 36 B(int i){ 37 A(); 38 a = i; 39 } 40 void fun(){ 41 cout << a << endl; //正确,public成员。 42 cout << a1 << endl; //正确,基类public成员,在派生类中变成了private,可以被派生类类内访问。 43 cout << a2 << endl; //正确,基类的protected成员,在派生类中变成了private,可以被派生类类内访问。 44 cout << a3 << endl; //错误,基类的private成员不能被派生类访问。 45 } 46 }; 47 int main(){ 48 B b(10); 49 cout << b.a << endl; //正确。public成员 50 cout << b.a1 << endl; //错误,private成员不能在类外访问。 51 cout << b.a2 << endl; //错误, private成员不能在类外访问。 52 cout << b.a3 << endl; //错误,private成员不能在类外访问。 53 system("pause"); 54 return 0; 55 }
以上的代码都备有较为详尽的注释,读者应该能够理解。仔细看代码中派生类B中定义了和基类同名的成员a,此时基类的a仍然存在,可以验证。
1 int main(){ 2 cout << sizeof(A) << endl; 3 cout << sizeof(B) << endl; 4 5 system("pause"); 6 return 0; 7 }
输出:
16
20
所以派生类包含了基类所有成员以及新增的成员,同名的成员被隐藏起来,调用的时候只会调用派生类中的成员。
如果要调用基类的同名成员,可以用以下方法:
1 int main(){ 2 3 B b(10); 4 cout << b.a << endl; 5 cout << b.A::a << endl; 6 7 system("pause"); 8 return 0; 9 }
输出:
10
4
记得这里是在类外访问,而a在基类中是public,所以B的继承方式应为public,从而保证a在派生类中仍然为public,在类外可以访问。