【问题标题】:do operator methods occupy memory in c++ objects?运算符方法是否占用 C++ 对象中的内存?
【发布时间】:2014-02-08 00:02:21
【问题描述】:

假设我有一些简单的类/结构,除了数据和少数几个运算符之外没有其他任何东西。如果我理解的话,一个在 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) 的计算结果仍然是真的吗?是否有不会增加内存中对象大小的运算符/方法?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 虚函数呢?
    • @GuyGreer:好吧,在某些实现中,您需要考虑一个 vtable。但是函数本身永远不会存储在对象中。
    • 你能解释一下填充和对齐是什么意思吗?是否有任何原因,例如SomeStruct structArray[100]float floatArray[100] 的大小不同?
    • 嗯,我没有任何书籍讨论编译器如何为 c++ 对象或对象数组分配内存。你有没有想到一个呢?标准中是否指定了对象内存的打包方式?我从未参加过涵盖这些主题的课程(主要是因为我没有计算机科学学位)
    • @xaviersjs:如果您的书没有教授对齐、填充和字节序的基础知识,那么您需要一本新书! http://stackoverflow.com/questions/388242/…
    【解决方案2】:

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

    答案是“视情况而定”。

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

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

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

    【讨论】:

      【解决方案3】:

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

      ==> 大小没有变化。

      【讨论】:

      • 投反对票是为了什么?我没有提到虚拟功能的情况如何变化? ://
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-23
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      • 2012-01-29
      相关资源
      最近更新 更多