我仍然是C ++新手。刚开始读到类的静态成员函数不是特定于对象的 - 所有对象的成员函数都有一个副本。
现在我脑子里出现了两个问题:
普通功能和静态功能“仅在内存分配方面”有什么区别?
如果成员函数包含一些局部变量怎么办?在这种情况下,函数“应该”具有该变量的单独副本 - 特定于调用该函数的对象...如何在C ++中解决此问题?
谢谢!
答案 0 :(得分:9)
有什么区别 普通功能和静态功能 功能“在记忆方面 仅分配“?
无。除了范围之外,静态函数就像一个全局函数。
即使对于非静态成员函数,也不需要额外的内存。成员函数int C::f(int arg1, int arg2)
只是int C__f(C* this, int arg1, int arg2)
之类的语法糖。
如果成员函数包含,该怎么办? 一些局部变量?在这种情况下 功能“应该”有一个单独的 该变量的副本 - 特定于 调用函数的对象......
该函数的每个调用都有一个局部变量的副本(除非它们是static
)。这就是C ++中可能的递归。
C ++中如何解决这个问题?
函数调用基于“堆栈帧”。堆栈框架包括:
this
)。static
局部变量。每当调用函数时,都会创建一个堆栈帧。当函数是,堆栈帧被破坏。如果以递归方式调用函数,则每个递归级别都会获得自己的堆栈帧。例如,如果你有
int factorial(int n) {
if (n <= 1)
return 1;
else
return factorial(n - 1) * n;
}
然后当你调用factorial(3)
时,会像这样创建一个堆栈框架:
------------------------ stack pointer (SP)
n = 3
RA = <in main()>
当对factorial(2)
进行递归调用时,会在堆栈顶部添加一个额外的框架
------------------------ SP
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>
另一个递归调用是factorial(1)
。
------------------------ SP
n = 1
RA = <in factorial()>
------------------------
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>
这是递归的基本情况,返回值1存储在寄存器中。函数调用完成后,顶层堆栈帧被销毁,并在保存的返回地址继续执行。
------------------------ SP
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>
现在,对factorial(2)
的调用可以计算其返回值(2),并且可以销毁另一个堆栈帧:
------------------------ SP
n = 3
RA = <in main()>
最后,我们可以计算原始函数调用的结果(6),并破坏这个堆栈帧。
答案 1 :(得分:4)
答案 2 :(得分:2)
我发现不太可能存在差异
您似乎应该阅读一下堆和堆栈分配之间的区别。这可以很好地了解内存如何在较低但仍处于较高水平的情况下工作。对不起,我现在不能提供更多帮助。
编辑:太慢了:))
答案 3 :(得分:0)
确实没有那么大的区别。两者都只存储在内存中一次,当调用非静态方法时,除了所有函数之外,指向当前对象的指针(this指针)被压入堆栈(或存储在ECX中,具体取决于您的编译器)参数。静态函数不需要类的实例,因此它就像常规的C函数一样被调用。
与使用调用堆栈的C相同。