运算符方法会占用c++对象中的内存吗

do operator methods occupy memory in c++ objects?

本文关键字:内存 对象 c++ 方法 运算符      更新时间:2023-10-16

假设我有一些简单的类/结构,除了数据和一些选择的运算符之外什么都没有。如果我理解的话,C++中只有数据的基本结构,就像C一样,占用的内存和成员一样多。例如,

struct SomeStruct { float data; }
sizeof(SomeStruct) == sizeof(float); // this should evaluate to true

我想知道的是,在类中添加运算符是否会使对象在内存中变得更大。例如

struct SomeStruct
{
public:
SomeStruct & operator=(const float f) { data = f; return this; }
private:
float data;
}

CCD_ 1评估为true仍然是真的吗?是否存在不会增加内存中对象大小的运算符/方法?

结构可能不一定只有其成员那么大(考虑填充和对齐),但您基本上是正确的,因为:

函数不是数据,也不"存储"在对象类型中

也就是说,在向类型中添加虚拟函数的情况下,请注意添加虚拟表指针。这是该类型的一次性大小增加,在添加更多虚拟函数时不会重新应用。

我想知道的是,向类中添加运算符是否会使对象在内存中变得更大。

答案是"取决于情况"。

如果在添加函数之前类不是多态的,并且这个新函数使类保持非多态性,那么添加这个非多态函数对类实例的大小没有任何影响。

另一方面,如果添加这个新函数确实使类具有多态性,那么这个添加将使类的实例更大。大多数C++实现都使用虚拟表,简称vtable。多态类的每个实例都包含一个指向该类的vtable的指针。非多态类的实例不需要,因此不包含vtable指针。

最后,向已经多态的类中添加另一个虚拟函数并不会使类实例变大。这个添加确实使该类的vtable变大,但vtable本身不是实例的一部分。vtable指针是实例的一部分,而该指针已经是类布局的一部分了,因为类已经是多态的。

当我学习C++和OOP时,我在某个地方(一些糟糕的来源)读到C++中的对象本质上与内部有函数指针的C结构相同。它们在功能上可能是这样的,但如果它们真的是这样实现的,那将是巨大的空间浪费,因为所有对象实例都必须存储相同的指针。

方法代码存储在一个中心位置,C++只是让它看起来很方便,好像每个实例都有自己的方法。(运算符本质上是具有不同语法的函数)。

在类中定义的方法和运算符不会增加实例化对象的大小。你可以自己测试:

#include <iostream>
using namespace std;
struct A {
int a;
};
struct B {
int a;
//SOME RANDOM METHODS AND OPERATORS
B() : a(1) {cout<<"I'm the constructor and I set 'a' to 1"<<endl;}
void some_method() const { for(int i=0;i<40;i++) cout<<"loop";}
B operator+=(const B& b){
a+=b.a;
return *this;
}
size_t my_size() const { return sizeof(*this);}

};
int main(){
cout<<sizeof(A)<<endl;
cout<<B().my_size()<<endl;
}

64位系统的输出:

4
I'm the constructor and I set 'a' to 1
4

===>尺寸不变。