C++变量的“总分性”(Mereology)
Stroustrup 在自传中说自己在哲学上深受 Kierkegaard (吉爾凱高爾)的影响,而讨厌黑格尔。所以看 Stroustrup 的书,很少感受到抽象理论的重要性。这也影响了C++的文化:许多C++程序员很会写代码,但是概念说不清楚,感觉生活很难( :)。 这多多少少怪C++的鼻祖 Stroustrup 本人。
闲话少说,关于C++变量的属性问题,是C++最根本的问题。然而我还没有读过一本书能从抽象,理论高度说清楚的。今天我就试图谈谈C++变量的属性。我认为,每个C++变量有六个无法分离的属性(把名和类合并),理解了,你就入了C++的门:
数据类型和名字
C++中没有“未知类”变量
C++的变量用名字的唯一性来辨识,同一scope中没有同名的变量
存储类型(storage class)
数据段(data segment)变量
堆栈(stack) 变量
堆叠(heap) 变量:(只能是分变量)
适用范围(scope):
1。默认名空间( :: namespace)
2。命名空间( named namespace)
3。无名空间(anonymous namespace):文件变量
4。型 (static class variable or type variable)
5。实例(instance class member variable)
6。函数内 - 静态 (static variable in a function)
7。函数内(或代码块内)- 动态 (auto variable or stack variable)
生命周期
程序初始至结束:global
代码块(code block): auto
New/delete: free
第一次使用至程序结束: static in function
内容:
直接内容
直接变量
间接内容
指针变量
引用变量
总分性(Mereology)
总(whole variable)变量
分(part variable) 变量:即成员变量
前四个属性都有著述,而第五,六个属性似乎无人或鲜有人提出。
关于“总分性”,该词这是我在查Mereology翻译时找到的唯一较好的翻译。我几乎找不到有前人论述的信息(知道的请告诉我)。
他的意思是“总体”与“部分”的关系。翻译成总部也不好,总分亦不完美,但是比总部稍稍谦虚点:)
有了这个概念,我们可以进一步区分两种变量:
A. 独立变量:是个总体,不属于任何变量,或可称为“母变量”
B. 成员变量:是个部分体,隶属一个总变量,或可称为“子变量”
为什么总分性对于一个变量很重要呢?因为:
1) 一个存储属性为 Heap 的变量只能为子变量。
A* pA = new A; //line1
pA是指针变量,它本身不在heap中,它只是“指向Heap地址”。
如果A定义为: class A { B b;},那么line1导致了子变量b的存储属性是Heap.
从另一个角度说,Heap中的母变量总是无名的,它只有通过指针间接地存在。
2) 子变量的存储属性决定于母变量的存储属性
比如 class A { }; class B { A *pA; };foo(){B b;}
b 作为母变量,存储属性是堆栈,而它的子变量 pA,也在堆栈中。如果B *b = new B,那么 pA 的属性就是 Heap。
3)子变量在运行时可以被优化成其母变量的“域”,所以它的读/写是通过它的母变量进行的,不用单独“取址”(即按名取址),性能较母变量稍好。
比如b.f1可以被优化为b+offsetof(f1), f1在运行时被“抹去名字”。
总之
理解C++变量的六大属性,是深入理解C++变量,也是C++语义的重要一环。由于“总分性”的概念不为专家强调,这里专门著文小序,以期抛砖引玉。
C++变量的“总分性”(Mereology)的更多相关文章
- 连续型变量的推断性分析——t检验
连续型变量的推断性分析方法主要有t检验和方差分析两种,这两种方法可以解决一些实际的分析问题,下面我们分别来介绍一下这两种方法 一.t检验(Student's t test) t检验也称student ...
- 探究foreach对于迭代变量的封装性的研究
众所周知教科书上对于foreach之中的注释是在遍历过程中无法改变其遍历的元素例如声明一个数组 ,,,}; foreach(int m in ii){ m = ;//错误 “m”是一个“foreach ...
- bash脚本编程之一 变量、变量类型等
变量的内容 1.变量命名: 1.只能包含字母.数字和下划线,并且不能以数字开头, 2.不应该跟系统中已有的环境变量重名 3.最好能见名知意 2.变量赋值: 设置变量: ...
- 【22】将成员变量声明为private
1.为什么要将成员变量声明为private,语法一致性,只通过方法暴露接口. 2.使用方法,可以对成员变量更精确的控制.比如:为所有可能的实现提供弹性,不同实现可以替换:控制可读可写:验证约束条件:处 ...
- Java 类 ThreadLocal 本地线程变量
前言:工作中将要使用ThreadLocal,先学习总结一波.有不对的地方欢迎评论指出. 定义 ThreadLocal并不是一个Thread,而是Thread的局部变量.这些变量不同于它们的普通对应物, ...
- 条款22:将成员变量声明为private
protected成员变量的封装性并非高于public变量. 如果有个public的成员变量,一旦其需要改变,那么所有使用它的代码都需要改变. 如果有个protected的成员变量,一点其需要改变,那 ...
- Effective C++:条款22:将成员变量声明为private
(一)为什么不採用public成员变量 (1)首先,从语法一致性考虑,客户唯一能訪问对象的方法就是通过成员函数,客户不必考虑是否该记住使用小括号(). (2)其次,使用函数能够让我们对成员变量的处理有 ...
- Linux Shell 高级变量及字符串
高级变量包含三个部分1.变量扩展2.命令替换3.算术扩展在Bash Shell中,$算符会触发到上述三种扩展,基本形式如下: 基本型 扩展种类 例子 ...
- 六 BASH 高级变量
高级变量分为三类 变量扩展 ${变量名} 例 ${filename} 大括号 命令替换 $(命令) $(ls /) 小括号 算术扩展 $((算数式)) $(( ...
随机推荐
- 把CSV文件导入到SQL Server表中
保存数据库数据直接查询select * from tableName 在数据表格的左上角右击——将结果另存为选择路劲保存好的就是.csv格式的数据 有时候我们可能会把CSV中的数据导入到某个数据库的表 ...
- swiper 多个循环的实现
swiper 最好要一一对应,最好与id关联. new Swiper('#guess .swiper-container', { pagination: '#guess .swiper-paginat ...
- Python修饰器
Python的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西.虽然好像,他们要干的事都 ...
- 【26】Remove Duplicates from Sorted Array
[26]Remove Duplicates from Sorted Array Given a sorted array, remove the duplicates in place such th ...
- tyvj P1431 [Tyvj Jan]分配任务(最大流)
P1431 [Tyvj Jan]分配任务 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 随着tyvj发展越来越大,管理员的任务越来越重,如何合理的 ...
- viewWillLayoutSubView
当viewController的bounds又改变,调用这个方法来实现subview的位置.可重写这个方法来实现父视图变化subview跟着变化. > Lif ...
- MyBatis架构图
MyBatis架构 MyBatis依赖的jar不多,而且代码行数也没多少,其中使用了大量的设计模式,值得好好学习.下图是MyBatis的一张架构图,来自Java框架篇—Mybatis 入门. Myba ...
- adb logcat命令查看并过滤android输出log
cmd命令行中使用adb logcat命令查看android系统和应用的log,dos窗口按ctrl+c中断输出log记录. logcat日志中的优先级/tag标记: android输出的每一条日志都 ...
- quartz 定时任务的实现
需求:项目中有一个任务,当时间到了会向移动端通过百度云推送推送信息,之前很傻叉的是写一个多线程一直扫描,每分钟扫描一次,比对当前时间和任务时间是否一样,结果把 项目跑死了,项目中用了一个简单的quar ...
- 小菜学习Lucene.Net(更新3.0.3版本使用)
花了两天的时间研究了下Lucene.Net 发现确实挺好玩.... 最新版本是3.0.3 (最后更新时间2012-10) 可惜3.0.3版本的Lucene.net无法和盘古分词 (最新版为2.3.1. ...