明明白白c++之类的基本操作(c++ primer 的读书笔记 ,类对象, 类用户, 类成员的含义)

来源:互联网 发布:安卓软件搜索 编辑:程序博客网 时间:2024/06/05 04:20

转自:http://blog.csdn.net/mlkiller/article/details/8826461

一前言

看c++ primer有一个地方看的云里雾里的,这么一段话

可以认为 protected 访问标号是 private 和 public 的混合:
• 像 private 成员一样,protected 成员不能被类的用户访问。
• 像 public 成员一样,protected 成员可被该类的派生类访问。
此外,protected 还有另一重要性质:
• 派生类只能通过派生类对象访问其基类的 protected 成员,派生类对其基类类型对象的 protected 成员没有特殊访问权限


这里就完全看不明白了,可能是翻译的问题导致的,老外写的本来就有点绕,翻译过来就更加绕,很难理解。

那么我们以下面的代码为例子。大家先看看觉得那句话编译会报错。

我之前写的代码都是编译错了之后,自己再去修改,而没有特别仔细的去思考到底为什么定义为pubulic ,protected和private,总是到这里弄不清楚,稀里糊涂就过去了,为了弄清楚,敲了下面的代码,编译之后便一目了然了。

二分析代码

先自己分析一下,然后后面在公布答案。


[cpp] view plain copy
 print?
  1. class A   
  2. {  
  3. public:  
  4.         int set(A& a);  
  5.         int public_a_var;  
  6. protected:  
  7.         int protected_a_var;  
  8. private:  
  9.         int private_a_var;  
  10. };  
  11.   
  12.   
  13. int A::set(A &a)  
  14. {  
  15.         protected_a_var = a.protected_a_var;  
  16.         private_a_var = a.private_a_var;  
  17.         public_a_var = a.public_a_var;  
  18. }  
  19. class B:A  
  20. {  
  21.         public:  
  22.                 int anotherset(A& a, B& b);  
  23.                 int public_b_var;  
  24.         protected:  
  25.                 int protected_b_var;  
  26. private:  
  27.                 int private_b_var;  
  28. };  
  29.   
  30.   
  31. int B::anotherset(A& a, B& b)  
  32. {  
  33.         public_b_var = a.public_a_var ;  
  34.         public_b_var = b.public_b_var;  
  35.         protected_b_var = a.protected_a_var;  
  36.         protected_b_var = b.protected_b_var;  
  37.         private_b_var = a.private_a_var;  
  38.         private_b_var = b.private_b_var;  
  39.   
  40.   
  41.   
  42.   
  43.         public_a_var = a.public_a_var ;  
  44.         public_a_var = b.public_b_var;  
  45.         protected_a_var = a.protected_a_var;  
  46.         protected_a_var = b.protected_b_var;  
  47.         private_a_var = a.private_a_var;  
  48.         private_a_var = b.private_b_var;  
  49. }  
  50.   
  51.   
  52. int main()  
  53. {  
  54.         A main_a;  
  55.         int a = main_a.private_a_var;  
  56.         int b = main_a.protected_a_var;  
  57.         int c = main_a.public_a_var;  
  58. }  


三含义介绍

1 类成员的含义

首先说一下概念,c++ primer里面类成员,类对象,类用户,这些词语在c++ primer里面用的乱七八糟的,让人看着很费解,如果你本身又是学过别的c++的书籍,看到上面的一段话估计要崩溃的,讲的是嘛啊?

2 类对象的含义

先解释一下上面这句话:

这里类成员这个词没有任何歧义,就是指类里面的所有变量和函数。

类对象这个词存在歧义,而且这本书里面前后都不一样,要看语境了。

第一种是广义的

比如上文中的,main函数里面的main_a ,set函数里面的a,anotherset函数里面的a, b 都是类对象,而且这本书里面的大部分地方类对象就是广义的。

第二种是狭义的,专指类的成员函数里面的作为参数的类对象。

在某些语境里面,个人觉得一般是出现了类的用户这个词之后,类对象就变成狭义了。

上面那句话里面“派生类只能通过派生类对象访问其基类的 protected 成员”,

其实这里可以这么理解吧,派生类的进行什么操作,描述的就是类的函数了,前面加入了条件限制了,那么这个类对象自然就也被限定了起来。

不过读起来就很费劲了。


3 类的用户

这个词语在一般的c++书上貌似是看不到的,突然之间冒出来一个类的用户,就突然感觉复杂了很多。

其实如果第一句话修改为:

像 private 成员一样,protected 成员不能被类的对象访问。

这个时候,你在看第三句话,就会有疑问,既然protect成员不能被类的对象访问,那怎么又派生类只能通过派生类对象访问其基类的 protected 成员”,这不是前后矛盾么?

其实并不矛盾,作者也是怕用户看到这里看糊涂了,就引入了类的用户。

类的用户,可以专门指外部函数里面的类的对象,例如main函数里面的main_a ,其他几个就不是类的用户了。


四进一步分析

我们分析一下上面的这一段话,其实有一个前提,没说说明白。

因为作者认为大部分人都应该知道,所以就没有说,也没有强调,但是很多人都是半生不熟的c++然后来看这本书,知道它是经典,但是不知道它不是prime,至少你得写了一年的c++代码,至少你得吃过苦头才能明白。

废话不说了,前提是:

类的成员函数中的类对象,可以访问自己的所有类型的成员。

换句话说,狭义的类对象,可以访问自己的所有类型的成员。

类的成员函数中其实是个定语,虽然很长。

第三句话的前半段,“派生类只能通过派生类对象访问其基类的 protected 成员”,因为派生类已经继承了基类,所以protected也是它自己的成员,基于这个前提,它狭义的类对象,自然可以访问自己的protected变量。

第三局话的后半段,当基类对象作为参数的时候,这句话更绕,我们用继承类代替前面那句话的类,就是由于基类对象不属于继承类的成员函数的继承类对象,所以它本质上不属于这个继承类的对象,所以它的权限就和类的用户是一样的。


五分析代码

上面已经把人说晕了,我分析下代码吧。

[cpp] view plain copy
 print?
  1. int A::set(A &a)  
  2. {  
  3.         protected_a_var = a.protected_a_var;  
  4.         private_a_var = a.private_a_var;  
  5.         public_a_var = a.public_a_var;  
  6. }  

这三句话都正确。

这里有两个概念,protected_a_var ,private_a_var已经public_a_var实质是this.开头的,指的是类的成员(其实也是类当前对象的成员),入参是类型A的对象a,由于类型一样,所以可以操作a的任何变量。

这个原理我不知道,面向对象的思想吧,其实面向对象就是仿照人类社会。我们可以这么理解如果大家是一类,或者看成一家人,在构建这个家庭的时候,我们内部的各种东西都是共享的。

但是当我们出了这个家门,在外面的时候,只有我们家公共的信息可以告诉别人,但是私有的密码,必然家里多少钱,银行密码之类的就不能说了。

[cpp] view plain copy
 print?
  1. int B::anotherset(A& a, B& b)  
  2. {  
  3.         public_b_var = a.public_a_var ;  
  4.         public_b_var = b.public_b_var;  
  5.         protected_b_var = a.protected_a_var;  
  6.         protected_b_var = b.protected_b_var;  
  7.         private_b_var = a.private_a_var;  
  8.         private_b_var = b.private_b_var;  
  9.   
  10.   
  11.   
  12.   
  13.         public_a_var = a.public_a_var ;  
  14.         public_a_var = b.public_b_var;  
  15.         protected_a_var = a.protected_a_var;  
  16.         protected_a_var = b.protected_b_var;  
  17.         private_a_var = a.private_a_var;  
  18.         private_a_var = b.private_b_var;  
  19. }  

看看这段代码,继承其实就像分家了,我们有一些共有的东西,也有一些私有的东西,但是也不是特别的贴切这个比喻。这样吧,就像娶老婆了。老婆说,你的都是我的,我的还是我的。其实都不贴切,如果大家看过龙珠的话,可以这么认为,就像是那美克星人的生殖,儿子继承类父亲的所有能力,而且自己还会不断进步。

废话不说了,我们还是分析加上必要的记忆吧。

先看前六句:

我们根据上面的理解,赋值语句前面的变量,class B都可以访问,后面的如果类型是class B的因为是一家人都可以访问,a 的只能访问public类型的,所以结果为

[cpp] view plain copy
 print?
  1.               public_b_var = a.public_a_var ;  
  2. public_b_var = b.public_b_var;  
  3. protected_b_var = a.protected_a_var;//错误,a.protected_a_var是保护的。  
  4. protected_b_var = b.protected_b_var;  
  5. private_b_var = a.private_a_var;//错误,a.private_a_var是私有的  
  6. private_b_var = b.private_b_var;  

下面六句话,继承的时候,继承类的成员只能访问protect和pirvate所以结果如下

[cpp] view plain copy
 print?
  1.               public_a_var = a.public_a_var ;  
  2. public_a_var = b.public_b_var;  
  3. protected_a_var = a.protected_a_var;//错误,a.protected_a_var是保护的。  
  4. protected_a_var = b.protected_b_var;  
  5. private_a_var = a.private_a_var;// 两个错误,private_a_var 和a.private_a_var都不能访问,是私有的  
  6. private_a_var = b.private_b_var;//private_a_var是私有的,赋值语句前面的那个  

最后分析main函数里面的


[cpp] view plain copy
 print?
  1. int a = main_a.private_a_var;//错误,a.private的私有  
  2. int b = main_a.protect_a_var;//错误,a.protect是保护  
  3. int c = main_a.public_a_var;  

6 结果。

大家可以编译测试一下:上面文章有原因,本来想标记为红色,但是代码类型的不会标记,如果有达人知道,希望在评论里面回复一下,便于大家查看代码。

[cpp] view plain copy
 print?
  1. class A   
  2. {  
  3. public:  
  4.         int set(A& a);  
  5.         int public_a_var;  
  6. protected:  
  7.         int protected_a_var;  
  8. private:  
  9.         int private_a_var;  
  10. };  
  11.   
  12.   
  13. int A::set(A &a)  
  14. {  
  15.         protected_a_var = a.protected_a_var;  
  16.         private_a_var = a.private_a_var;  
  17.         public_a_var = a.public_a_var;  
  18. }  
  19. class B:A  
  20. {  
  21.         public:  
  22.                 int anotherset(A& a, B& b);  
  23.                 int public_b_var;  
  24.         protected:  
  25.                 int protected_b_var;  
  26. private:  
  27.                 int private_b_var;  
  28. };  
  29.   
  30.   
  31. int B::anotherset(A& a, B& b)  
  32. {  
  33.         public_b_var = a.public_a_var ;  
  34.         public_b_var = b.public_b_var;  
  35.         protected_b_var = a.protected_a_var;//error  
  36.         protected_b_var = b.protected_b_var;  
  37.         private_b_var = a.private_a_var;//error  
  38.         private_b_var = b.private_b_var;  
  39.   
  40.   
  41.   
  42.   
  43.         public_a_var = a.public_a_var ;  
  44.         public_a_var = b.public_b_var;  
  45.         protected_a_var = a.protected_a_var;//error  
  46.         protected_a_var = b.protected_b_var;  
  47.         private_a_var = a.private_a_var;//error  
  48.         private_a_var = b.private_b_var;//error  
  49. }  
  50.   
  51.   
  52. int main()  
  53. {  
  54.         A main_a;  
  55.                 int a = main_a.private_a_var;//error  
  56.         int b = main_a.protected_a_var;//error  
  57.         int c = main_a.public_a_var;  
  58. }  
阅读全文
0 0
原创粉丝点击