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;}

作为母变量,存储属性是堆栈,而它的子变量 pA,也在堆栈中。如果B *b = new B,那么 pA 的属性就是 Heap

3)子变量在运行时可以被优化成其母变量的“”,所以它的读/写是通过它的母变量进行的,不用单独“取址”(即按名取址),性能较母变量稍好。

比如b.f1可以被优化为b+offsetof(f1), f1在运行时被“抹去名字”。

总之

理解C++变量的六大属性,是深入理解C++变量,也是C++语义的重要一环。由于“总分性”的概念不为专家强调,这里专门著文小序,以期抛砖引玉。

时间: 2024-10-29 19:11:54

C++变量的“总分性”(Mereology)的相关文章

探究foreach对于迭代变量的封装性的研究

众所周知教科书上对于foreach之中的注释是在遍历过程中无法改变其遍历的元素例如声明一个数组 int[] ii={0,1,2,3}; foreach(int m in ii){ m = 3;//错误 “m”是一个“foreach 迭代变量”,无法为它赋值 Console.WriteLine(m); } 由上面可以知道,我们无法改变数组里面的值,但是foreach语句是为了集合而创建的,数组只是集合的一种,而其他集合会是怎么样的呢?C#里面为我们创建好了好几个集合类,List<T> ,Arra

连续型变量的推断性分析——方差分析(2)

前面我们介绍了差异分解的方差分析思路,这是最初始的方差分析思想,随着线性模型的发展,人们又将线性模型的思想引入了方差分析,大大提升了这一分析方法的发展空间,下面我们来介绍一下线性模型在方差分析中的体现.任何一次实验结果都可以表示成如下形式: Yi=μ+εi 其中Yi是第i次实验的实际结果,μ是该结果的最佳估计值,其实就是总体均值,εi是均值和实际结果的偏差也就是随机误差,为了方便推导,我们假定εi服从均值为0,标准差为某个定值的正态分布,这也是前面讲到的方差分析的适用条件之一. 我们把以上形式按

linux之bash变量

bash变量之高级部分 1.变量扩展 ${变量名称}                     变量扩展                          例如:${filename} $(命令)                            命令替换                          例如:$(ls /) $((算术式))                       算式扩展                          例如:$((9+9)) 变量扩展:一种简易的条

Effective C++:条款22:将成员变量声明为private

(一)为什么不采用public成员变量 (1)首先,从语法一致性考虑,客户唯一能访问对象的方法就是通过成员函数,客户不必考虑是否该记住使用小括号(). (2)其次,使用函数可以让我们对成员变量的处理有更精确的控制.如果我们令成员变量为public,那么每个人都可以读写它! 但如果我们以函数取得或设定其值,我们就可以实现出"不准访问"."只读访问"以及"读写访问",我们甚至可以实现"惟写访问". class AccessLeve

【总结】C++静态成员变量的特性总结及测试用例

静态成员变量存放于数据段,在编译时产生,故有以下特性:    静态成员变量实际为类域中的全局变量,其初始化也应与全局变量一样,不能再头文件里初始化,应与全局变量初始化的方式一样,初始化时,静态成员变量不收访问限定符限定 Test.cpp: class A { static int _num; }; int A::_num = 0;//初始化成功 静态成员变量被类内所有成员变量共享,也被派生类所有成员变量共享 class B :public A { }; int main() { A a; a._

Linux Shell之三 高级变量及字符串

高级变量包含三个部分1.变量扩展2.命令替换3.算术扩展在Bash Shell中,$算符会触发到上述三种扩展,基本形式如下:    基本型             扩展种类            例子            ${变量名称}            变量扩展        ${filename}$(命令)                命令替换        $(ls /)$((算术式))            算术扩展        $((5+3))变量存在表示变量有值(包含空)一

临时变量作为非const的引用进行参数传递引发的编译错误

1.错误原因即解决办法 Linux环境运行,使用g++编译,观察如下代码,会出现: invalid initialization of non-const reference of type 'std::string&' from a temporary of type 'std::string'的错误. 其中文意思为临时变量无法为非const的引用初始化.也就是在参数传递的过程中,出现错误.出错的代码如下: void print(string& str) { cout<<st

条款22:将成员变量声明为private

protected成员变量的封装性并非高于public变量. 如果有个public的成员变量,一旦其需要改变,那么所有使用它的代码都需要改变. 如果有个protected的成员变量,一点其需要改变,那么所有的继承自他的derived class都需要重新改变.这与上面孰轻孰重其实不重要 所以说,往往只有两种封装性质,private或者是不封装 小结: 切记将成员变量声明为private protected并不比public更具有封装性

征服C指针-C的变量种类

C语言的变量具有区间性的作用域.在开发一些小程序的时候也许我们并不在意作用域的必要性.可是,当你书写几万行,甚至几十万行的代码的时候,没有作用域肯定是不能忍受的.C语言有如下三种作用域. 1. 全局变量 在函数之外声明的变量,默认地会成为全局变量.全局变量在任何地方都是可见的.当程序被分割为多个源代码文件进行编译时,声明为全局变量的变量也是可以通过关键字extern从其他源代码文件中引用的. 2. 文件内部的静态变量 就算对于像全局变量那样呗定义在函数外面的变量,一旦添加了static,作用域就