Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 私有函数/方法如何在堆栈上标记?_C++_Oop - Fatal编程技术网

C++ 私有函数/方法如何在堆栈上标记?

C++ 私有函数/方法如何在堆栈上标记?,c++,oop,C++,Oop,执行方法/函数时,会在堆栈上创建一个。激活记录通常包括: 参数 局部变量 回信地址 返回结果地址 中间结果 上面的列表并没有说明函数/方法是否为Public/Private 所以我的问题是:仅仅通过观察运行时堆栈,函数/方法是如何“标记”的 堆栈来确定它们是公有/私有的,在C++、java或C++中, < p>我只回答 C++ >强>,而不是java。你不应该用多种语言来标记你的问题。不同语言的答案,即使是与C语言和C++语言紧密相关的语言,也会有很大的不同。 再 “执行方法/函数时,会在

执行方法/函数时,会在堆栈上创建一个。激活记录通常包括:

  • 参数
  • 局部变量
  • 回信地址
  • 返回结果地址
  • 中间结果
上面的列表并没有说明函数/方法是否为Public/Private

所以我的问题是:仅仅通过观察运行时堆栈,函数/方法是如何“标记”的
堆栈来确定它们是公有/私有的,在C++、java或C++中,

< p>我只回答<强> C++ >强>,而不是java。你不应该用多种语言来标记你的问题。不同语言的答案,即使是与C语言和C++语言紧密相关的语言,也会有很大的不同。

执行方法/函数时,会在堆栈上创建激活记录

不,不一定。此外,常用的术语是堆栈帧。堆栈帧通常是执行异常堆栈展开以及支持调试所必需的,但在特殊情况下(特别是内联,但也只是一般优化,如尾部递归调用的优化),不需要建立新的堆栈帧

堆栈框架的许多基本原理与一些关于工具和支持一般递归函数的理想想法有关。事情并非总是这样。例如,旧Fortran由于不支持递归而速度惊人,当Donald Knuth写他的《计算机编程的艺术》时,他只是让调用者将返回地址直接存储在被调用函数的返回指令中(但随后他也做了一些非常奇怪的事情,比如在机器代码级别抽象出十进制和二进制之间的差异,在第一版中画出根朝下的树结构,以及推测“卷轴时间”与磁带的安装有关)


仅通过查看堆栈,如何在堆栈上“标记”函数/方法以确定它们是公共的还是私有的

他们不是

<>机器代码级别没有C++可访问性。


<> >访问说明符对结构布局有影响。正如C++ 03,只有保证访问指定者之间成员的地址增加,我认为仍然适用于C++ 11和C++ 14。C++中的< /P> < P>,访问限制是用于名称,而不是函数、数据或 所有名称,包括嵌套类型都会受到影响,但仅限于 名称;您仍然可以从外部调用私有函数 类,前提是您可以以某种方式引用它(例如,通过指向 成员函数,或者仅仅因为它在基类中不是私有的 声明它是虚拟的)

Java基本上是相同的,尽管函数是私有的 这意味着它也是
最终的
,而不是
虚拟的
(事实并非如此)
在C++中,<>代码>虚拟函数通常是私有的当函数被执行时,函数是公共的或私有的,这是不相关的。至少在C++中,编译器确保你不从你不应该的地方调用私有函数。可视性是编译时关注的。它是如此简单。在C++中,至少不是。访问说明符限制编译时使用名称,我不知道Java会做什么;你应该一次只使用一种语言。事实并非如此。
public
private
之间的差异在编译时会产生不同;它让程序员控制类用户可以调用什么方法,并帮助防止调用方调用时发生意外这是一个不应该的方法。它对程序执行过程中发生的事情没有影响。是什么让你认为它们的访问修饰符对堆栈框架有任何影响?在所有这些语言中,它都充当访问控制,因此编译器只能从所需的位置确保它们的使用。在Java和C#中,它还充当封装机制m(在C++中,你必须使用pIMPL成语来实现封装)。但是除此之外,公共和非公共方法之间没有区别,它们都只是(子)。例程和以相同的方式调用。我不确定我是否同意这里的所有内容。堆栈帧是实现激活记录的一种方式,但它不是唯一的方式;很久以前,我遇到了一个C编译器,它通过在堆上动态分配内存(并在离开函数时释放内存)来实现激活记录;在没有词法作用域的语言中,这是通常的方式。而今天,对递归的支持与速度没有多大关系,尽管在过去,机器没有堆栈,递归意味着模拟堆栈。顺便说一句,将返回地址存储在返回指令中,或者在函数之前存储在内存中,这在当时也是很常见的做法。克努特没有发明任何东西。@JamesKanze:堆栈框架和activ之间的术语区别由于前者与机器堆栈相关联,而后者是一个更一般的概念,因此目前并未广泛使用。相反,“堆栈帧”是当今的通用术语。对于使用Slooow动态分配堆栈帧的“C编译器:),这可能是C解释器,也可能是一种误解,就某人而言,是指在带有寄存器文件的机器上,事物是如何工作的;我猜是斯巴克车站。关于递归支持的速度成本,是的,这可能会随着时间的推移而改变。动态分配激活记录的C编译器位于BS2000上。西门子的机器(当时——现在的富士通)没有(我想现在也没有)堆栈。它确实大大减缓了速度。这种机器在过去很常见(现在仍然主导着大型机架构)