【转】深入理解C++中public、protected及private用法

首先明白以下两点:

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 }

运行结果:

【转】深入理解C++中public、protected及private用法

继承中的特点:

先记住:不管继不继承,上面的规则永远适用!

有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,在类外可以访问。
原文链接: https://www.cnblogs.com/codingmengmeng/p/6434150.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/249807

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月14日 上午3:58
下一篇 2023年2月14日 上午3:58

相关推荐