在this question about static methods in managed code之后,如果那里的答案与像c ++这样的非托管代码相关,我会很有意思。
我制作了数千个实例,我的问题主要是关于静态方法。与常规方法相比,这种方法可以节省内存吗?
谢谢你,对我英语不好抱歉。答案 0 :(得分:9)
所有方法都需要将二进制代码放在内存中才能运行。 static
和non-static
方法的可执行代码(很大程度上)是相同的。
两种类型的方法在内存中只需要一个位置,因此它们不会与类的每个实例一起复制。
现在让我们来看看一些代码:
class A
{
public:
void foo();
static void goo();
};
void A::foo()
{
004113D0 push ebp
004113D1 mov ebp,esp
004113D3 sub esp,0CCh
004113D9 push ebx
004113DA push esi
004113DB push edi
004113DC push ecx
004113DD lea edi,[ebp-0CCh]
004113E3 mov ecx,33h
004113E8 mov eax,0CCCCCCCCh
004113ED rep stos dword ptr es:[edi]
004113EF pop ecx
004113F0 mov dword ptr [ebp-8],ecx
}
004113F3 pop edi
004113F4 pop esi
004113F5 pop ebx
004113F6 mov esp,ebp
004113F8 pop ebp
004113F9 ret
void A::goo()
{
00411530 push ebp
00411531 mov ebp,esp
00411533 sub esp,0C0h
00411539 push ebx
0041153A push esi
0041153B push edi
0041153C lea edi,[ebp-0C0h]
00411542 mov ecx,30h
00411547 mov eax,0CCCCCCCCh
0041154C rep stos dword ptr es:[edi]
}
0041154E pop edi
0041154F pop esi
00411550 pop ebx
00411551 mov esp,ebp
00411553 pop ebp
00411554 ret
int main()
{
A a;
a.foo();
0041141E lea ecx,[a]
00411421 call foo (4111E5h)
a.goo();
00411426 call A::goo (4111EAh)
return 0;
}
只有很小的差异,例如将this
指针推送到非静态函数的堆栈上,但它们很小,可能一个不错的优化器会进一步减少差异。
关于是否使用静态函数的决定应该严格地由设计驱动,而不是由内存驱动。
答案 1 :(得分:4)
静态方法本质上只是自由函数,因此它们的内存占用量是相同的。成员函数有一个额外的参数,所以增加的内存略大,虽然关心这些事情没有意义。
函数占用的内存量是每个类,而不是每个实例。你不应该担心。
答案 2 :(得分:2)
简答:不可以。方法是一个函数,隐含的第一个参数等于它的类,静态函数缺少第一个参数。实际上,情况与垃圾收集语言中的情况相同,因此其他问题的答案完全适用。
答案 3 :(得分:0)
static和instance方法之间的区别只是第一个参数。在C ++中,所有实例方法都使用一个名为 this 的替换第一个参数编译为普通函数,该参数是指向调用该方法的对象的指针。
在大多数体系结构中,这将是一个8字节的值,因此除非您正在进行一些资源非常严格的嵌入式系统编码,否则它并不重要。