每次创建新实例时,类是否必须为其非静态成员函数分配内存?
为了更好地说明这一点,如果我正在编写一个v3d
表示 3 空间向量的类,我会通过定义来使用更少的内存吗?
static v3d::dotProduct(v3d v1, v3d v2)
与
v3d::dotProduct(v3d v2)
?
每次创建新实例时,类是否必须为其非静态成员函数分配内存?
为了更好地说明这一点,如果我正在编写一个v3d
表示 3 空间向量的类,我会通过定义来使用更少的内存吗?
static v3d::dotProduct(v3d v1, v3d v2)
与
v3d::dotProduct(v3d v2)
?
每个实例都不会存储静态和非静态成员函数。在非静态成员函数的情况下,我理解的方式是它们被翻译成类似的东西(可能比这更不可读):
v3d_dotProduct(v3d this, v3d v2)
对它们的调用也会相应地进行翻译。如果你想提高性能,我建议使用内联函数,因为这些函数本质上是将函数内容复制到你调用它的地方。我认为这不会减少您的内存使用量,但值得将其用于每秒调用多次的类函数(静态和非静态)。
内存中有一个函数实例。它与静态与否无关。您不为成员函数分配内存。
或者,也许我误解了。也许您的意思是该函数以某种方式占用了对象中的空间?不,它没有。在目标代码级别,成员资格本质上只是一个名称约定和一个隐藏的“this”参数。如果是虚拟的,则通常有一个 vtable,所有实例都使用相同的 vtable。
但是,在您的示例中,您似乎正在按值传递所有 v3d 对象。这意味着在静态情况下,您制作 2 个对象副本(每个 arg 一个),而在非静态情况下,您只制作 1 个对象副本。
如果您通过引用传递 args,则可以避免复制 - 除非点积算法可能要求,无论那是什么(很久以来我没有做过任何数学)。
在任何一种情况下,函数的代码在代码内存中都只有一个副本。静态函数使用相同数量的代码内存,但使用更少的堆栈内存,因为当它们被调用时,堆栈上传递的参数少了。非静态类成员函数有一个附加参数(this 指针),在调用时会添加到堆栈中。如果你没有在对象中使用任何需要使用“this”指针的东西,你应该将函数声明为静态的。
您将节省的堆栈内存量可能微不足道。但是,如果函数每秒被调用数百万次,则静态函数可以看到速度的提高,因为不必在堆栈上传递额外的参数。