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

时间:2014-01-18 16:10:48

标签: c++ object memory operators operator-overloading

假设我有一些简单的类/结构,除了数据和选择少数运算符之外什么都没有。如果我理解,只有像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;
}

sizeof(SomeStruct) == sizeof(float)评估为真是真的吗?是否有任何操作符/方法不会增加内存中对象的大小?

3 个答案:

答案 0 :(得分:3)

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

函数不是数据,也不会“存储”在对象类型中。

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

答案 1 :(得分:2)

  

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

答案是“它取决于”。

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

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

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

答案 2 :(得分:-1)

当我学习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

==&GT;尺寸没有变化。