【转载】c++之类的基本操作(c++ primer 的读书笔记 ,类对象, 类用户, 类成员的含义)
一前言
看c++ primer有一个地方看的云里雾里的,这么一段话
可以认为 protected 访问标号是 private 和 public 的混合:
• 像 private 成员一样,protected 成员不能被类的用户访问。
• 像 public 成员一样,protected 成员可被该类的派生类访问。
此外,protected 还有另一重要性质:
• 派生类只能通过派生类对象访问其基类的 protected 成员,派生类对其基类类型对象的 protected 成员没有特殊访问权限
这里就完全看不明白了,freeeim可能是翻译的问题导致的,老外写的本来就有点绕,翻译过来就更加绕,很难理解。
那么我们以下面的代码为例子。大家先看看觉得那句话编译会报错。
我之前写的代码都是编译错了之后,自己再去修改,而没有特别仔细的去思考到底为什么定义为pubulic ,protected和private,总是到这里弄不清楚,稀里糊涂就过去了,为了弄清楚,敲了下面的代码,编译之后便一目了然了。
二分析代码
先自己分析一下,然后后面在公布答案。
- class A
- {
- public:
- int set(A& a);
- int public_a_var;
- protected:
- int protected_a_var;
- private:
- int private_a_var;
- };
- int A::set(A &a)
- {
- protected_a_var = a.protected_a_var;
- private_a_var = a.private_a_var;
- public_a_var = a.public_a_var;
- }
- class B:A
- {
- public:
- int anotherset(A& a, B& b);
- int public_b_var;
- protected:
- int protected_b_var;
- private:
- int private_b_var;
- };
- int B::anotherset(A& a, B& b)
- {
- public_b_var = a.public_a_var ;
- public_b_var = b.public_b_var;
- protected_b_var = a.protected_a_var;
- protected_b_var = b.protected_b_var;
- private_b_var = a.private_a_var;
- private_b_var = b.private_b_var;
- public_a_var = a.public_a_var ;
- public_a_var = b.public_b_var;
- protected_a_var = a.protected_a_var;
- protected_a_var = b.protected_b_var;
- private_a_var = a.private_a_var;
- private_a_var = b.private_b_var;
- }
- int main()
- {
- A main_a;
- int a = main_a.private_a_var;
- int b = main_a.protected_a_var;
- int c = main_a.public_a_var;
- }
class A
{
public:int set(A& a);int public_a_var;
protected:int protected_a_var;
private:int private_a_var;
};int A::set(A &a)
{protected_a_var = a.protected_a_var;private_a_var = a.private_a_var;public_a_var = a.public_a_var;
}
class B:A
{public:int anotherset(A& a, B& b);int public_b_var;protected:int protected_b_var;
private:int private_b_var;
};int B::anotherset(A& a, B& b)
{public_b_var = a.public_a_var ;public_b_var = b.public_b_var;protected_b_var = a.protected_a_var;protected_b_var = b.protected_b_var;private_b_var = a.private_a_var;private_b_var = b.private_b_var;public_a_var = a.public_a_var ;public_a_var = b.public_b_var;protected_a_var = a.protected_a_var;protected_a_var = b.protected_b_var;private_a_var = a.private_a_var;private_a_var = b.private_b_var;
}int main()
{A main_a;int a = main_a.private_a_var;int b = main_a.protected_a_var;int c = main_a.public_a_var;
}
三含义介绍
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变量。
第三局话的后半段,当基类对象作为参数的时候,这句话更绕,我们用继承类代替前面那句话的类,就是由于基类对象不属于继承类的成员函数的继承类对象,所以它本质上不属于这个继承类的对象,所以它的权限就和类的用户是一样的。
五分析代码
上面已经把人说晕了,我分析下代码吧。
- int A::set(A &a)
- {
- protected_a_var = a.protected_a_var;
- private_a_var = a.private_a_var;
- public_a_var = a.public_a_var;
- }
int A::set(A &a)
{protected_a_var = a.protected_a_var;private_a_var = a.private_a_var;public_a_var = a.public_a_var;
}
这三句话都正确。
这里有两个概念,protected_a_var ,private_a_var已经public_a_var实质是this.开头的,指的是类的成员(其实也是类当前对象的成员),入参是类型A的对象a,由于类型一样,所以可以操作a的任何变量。
这个原理我不知道,面向对象的思想吧,其实面向对象就是仿照人类社会。我们可以这么理解如果大家是一类,或者看成一家人,在构建这个家庭的时候,我们内部的各种东西都是共享的。
但是当我们出了这个家门,在外面的时候,只有我们家公共的信息可以告诉别人,但是私有的密码,必然家里多少钱,银行密码之类的就不能说了。
- int B::anotherset(A& a, B& b)
- {
- public_b_var = a.public_a_var ;
- public_b_var = b.public_b_var;
- protected_b_var = a.protected_a_var;
- protected_b_var = b.protected_b_var;
- private_b_var = a.private_a_var;
- private_b_var = b.private_b_var;
- public_a_var = a.public_a_var ;
- public_a_var = b.public_b_var;
- protected_a_var = a.protected_a_var;
- protected_a_var = b.protected_b_var;
- private_a_var = a.private_a_var;
- private_a_var = b.private_b_var;
- }
int B::anotherset(A& a, B& b)
{public_b_var = a.public_a_var ;public_b_var = b.public_b_var;protected_b_var = a.protected_a_var;protected_b_var = b.protected_b_var;private_b_var = a.private_a_var;private_b_var = b.private_b_var;public_a_var = a.public_a_var ;public_a_var = b.public_b_var;protected_a_var = a.protected_a_var;protected_a_var = b.protected_b_var;private_a_var = a.private_a_var;private_a_var = b.private_b_var;
}
看看这段代码,继承其实就像分家了,我们有一些共有的东西,也有一些私有的东西,但是也不是特别的贴切这个比喻。这样吧,就像娶老婆了。老婆说,你的都是我的,我的还是我的。其实都不贴切,如果大家看过龙珠的话,可以这么认为,就像是那美克星人的生殖,儿子继承类父亲的所有能力,而且自己还会不断进步。
废话不说了,我们还是分析加上必要的记忆吧。
先看前六句:
我们根据上面的理解,赋值语句前面的变量,class B都可以访问,后面的如果类型是class B的因为是一家人都可以访问,a 的只能访问public类型的,所以结果为
- public_b_var = a.public_a_var ;
- public_b_var = b.public_b_var;
- protected_b_var = a.protected_a_var;//错误,a.protected_a_var是保护的。
- protected_b_var = b.protected_b_var;
- private_b_var = a.private_a_var;//错误,a.private_a_var是私有的
- private_b_var = b.private_b_var;
public_b_var = a.public_a_var ;public_b_var = b.public_b_var;protected_b_var = a.protected_a_var;//错误,a.protected_a_var是保护的。protected_b_var = b.protected_b_var;private_b_var = a.private_a_var;//错误,a.private_a_var是私有的private_b_var = b.private_b_var;
下面六句话,继承的时候,继承类的成员只能访问protect和pirvate所以结果如下
- public_a_var = a.public_a_var ;
- public_a_var = b.public_b_var;
- protected_a_var = a.protected_a_var;//错误,a.protected_a_var是保护的。
- protected_a_var = b.protected_b_var;
- private_a_var = a.private_a_var;// 两个错误,private_a_var 和a.private_a_var都不能访问,是私有的
- private_a_var = b.private_b_var;//private_a_var是私有的,赋值语句前面的那个
public_a_var = a.public_a_var ;public_a_var = b.public_b_var;protected_a_var = a.protected_a_var;//错误,a.protected_a_var是保护的。protected_a_var = b.protected_b_var;private_a_var = a.private_a_var;// 两个错误,private_a_var 和a.private_a_var都不能访问,是私有的private_a_var = b.private_b_var;//private_a_var是私有的,赋值语句前面的那个
最后分析main函数里面的
- int a = main_a.private_a_var;//错误,a.private的私有
- int b = main_a.protect_a_var;//错误,a.protect是保护
- int c = main_a.public_a_var;
int a = main_a.private_a_var;//错误,a.private的私有int b = main_a.protect_a_var;//错误,a.protect是保护int c = main_a.public_a_var;
6 结果。
大家可以编译测试一下:上面文章有原因,本来想标记为红色,但是代码类型的不会标记,如果有达人知道,希望在评论里面回复一下,便于大家查看代码。
- <span style="font-size: 14px;">class A
- {
- public:
- int set(A& a);
- int public_a_var;
- protected:
- int protected_a_var;
- private:
- int private_a_var;
- };
- int A::set(A &a)
- {
- protected_a_var = a.protected_a_var;
- private_a_var = a.private_a_var;
- public_a_var = a.public_a_var;
- }
- class B:A
- {
- public:
- int anotherset(A& a, B& b);
- int public_b_var;
- protected:
- int protected_b_var;
- private:
- int private_b_var;
- };
- int B::anotherset(A& a, B& b)
- {
- public_b_var = a.public_a_var ;
- public_b_var = b.public_b_var;
- protected_b_var = a.protected_a_var;//error
- protected_b_var = b.protected_b_var;
- private_b_var = a.private_a_var;//error
- private_b_var = b.private_b_var;
- public_a_var = a.public_a_var ;
- public_a_var = b.public_b_var;
- protected_a_var = a.protected_a_var;//error
- protected_a_var = b.protected_b_var;
- private_a_var = a.private_a_var;//error
- private_a_var = b.private_b_var;//error
- }
- int main()
- {
- A main_a;
- int a = main_a.private_a_var;//error
- int b = main_a.protected_a_var;//error
- int c = main_a.public_a_var;
- }</span>
class A
{
public:int set(A& a);int public_a_var;
protected:int protected_a_var;
private:int private_a_var;
};int A::set(A &a)
{protected_a_var = a.protected_a_var;private_a_var = a.private_a_var;public_a_var = a.public_a_var;
}
class B:A
{public:int anotherset(A& a, B& b);int public_b_var;protected:int protected_b_var;
private:int private_b_var;
};int B::anotherset(A& a, B& b)
{public_b_var = a.public_a_var ;public_b_var = b.public_b_var;protected_b_var = a.protected_a_var;//errorprotected_b_var = b.protected_b_var;private_b_var = a.private_a_var;//errorprivate_b_var = b.private_b_var;public_a_var = a.public_a_var ;public_a_var = b.public_b_var;protected_a_var = a.protected_a_var;//errorprotected_a_var = b.protected_b_var;private_a_var = a.private_a_var;//errorprivate_a_var = b.private_b_var;//error
}int main()
{A main_a;int a = main_a.private_a_var;//errorint b = main_a.protected_a_var;//errorint c = main_a.public_a_var;
}
【转载】c++之类的基本操作(c++ primer 的读书笔记 ,类对象, 类用户, 类成员的含义)相关推荐
- 《C++ Primer》读书笔记
第一章 开始 类型:程序所处理的数据都保存在变量中,而每个变量都有自己的类型 内置类型:语言自身定义的类型(而形如string等类型都是标准库定义的) main的返回值:0表示成功,非0指出错误类型 ...
- C++ Primer Plus读书笔记
第五章 循环和关系表达式 1. 2.类别别名: (1) #define FLOAT_POINTER float * FLOAT_POINTER pa, pb; 预处理器置换将该声明转换成 flo ...
- C++ primer plus读书笔记与心得
C++Primer plus读书笔记与心得 2020年过年期间,因新型冠状肺炎影响,推迟复工.根据公司读书计划,将c++ primer plus 这本书复习了一遍,并将其中一些章节中自己记忆模糊或者之 ...
- C++ Primer Plus 读书笔记
C++ Primer Plus 0 内存模型,一些开始前的注意事项 存储持续性,作用域,链接性 常量 引用 1 对象和类 抽象和类 实现成员类函数 类的构造函数和析构函数 声明和定义构造函数 使用构造 ...
- 《C++ Primer》读书笔记 第三章
1.注意:头文件不应包含using声明.因为头文件的内容会拷贝到所有引用他的文件中去,对于某些程序来说,由于不经意间包含了一些名字,可能会产生名字冲突. 2.string类型的读入:用cin读入str ...
- 《C++ Primer Plus》读书笔记 第16章 string类和标准模板库
第16章 string类和标准模板库 1.string类 表16.1列出了string类的几个构造函数.其中NBTS(null-terminated string)表示以空字符结束的传统C-风格字符串 ...
- 《C++ Primer》读书笔记——第十三章_拷贝控制
一个类有5种特殊的成员函数:拷贝构造函数.拷贝赋值运算符.移动构造函数.移动赋值运算符.析构函数.如果没有定义这些拷贝控制成员,编译器会自动为它定义缺失的操作. A a; A b = a;//报错 1 ...
- C++ Primer Plus读书笔记第二章
自学了一段时间的C++打算还是要系统的整理一下一些知识点,让学习思路更清晰,不然老是学一点忘一点,这个读书笔记用来记录这段时间对C++ Primer Plus一书中知识点的记录,尽量会写的详细一点.直 ...
- [转载]我的《java与模式》读书笔记
我的<java与模式>读书笔记 中国是一个含蓄的民族,处对象一般都得通过一个介绍人. 这是一本阐述微观设计的书,而不是阐述宏观设计的书. <Java与模式>首先阐述了代码的设计 ...
最新文章
- 2015年国际智慧教育展览会盛大开幕
- SpringCloud之Hystrix
- HTTP协议中几个状态码
- xenserver 脚本学习之/opt/xensource/bin/xapi-wait-init-complete
- 算法设计与分析_算法设计与分析(第2版)第2章分治策略回顾
- python - 定时清理ES 索引
- Java笔记-WEB算术验证码
- 粗心能学计算机吗贴吧,考试丢分 , 真的是粗心那么简单吗?
- 数据分析工具具备什么功能
- Leetcode 刷题笔记(十八) —— 二叉树篇之二叉搜索树的修改与构造
- 支持linux的翻译软件,CentOS 6.4下安装翻译软件StarDict
- cfe刷机教程 斐讯k3_小白专属------K3官方固件CFE刷LEDE教程
- 三菱plc pwm指令_三菱PLC指令分享,看完就会
- Java零基础学习-每日单词(日更)
- ligerui中的一些知识点
- WordPress系列教程(一)----WordPress环境准备与安装
- CAD梦想画图中的“线宽设置”
- 北京大学智能学院成立!AI视觉泰斗朱松纯教授任院长
- 【WSAGetLastError】WSAGetLastError返回值
- Java生成唯一主键
热门文章
- 佳能c3320怎么设置接收方_入门级单反相机佳能800D是否值得买?在我看来价格决定一切...
- 通信系统概论_现代通信系统概论 第一章 概述(1)
- Linux6.8 ssh开启,CentOS 6.8升级 ssh到最新版SSH-8.2p1
- 用yum装程序 报[Errno 12] Timeout on Trying other mirror.
- java 抽象类 方法_java 抽象类
- 2021快手奢侈品行业数据价值报告
- 全面解码美妆消费者心智
- 作者:​邓波(1973-),男,博士,北京系统工程研究所研究员。
- 作者:张慧(1984-),女,中国科学院软件研究所助理研究员
- 作者:景志刚(1977-),男,现就职于中国人民银行征信中心数据部,主要研究方向为数据挖掘。...