【问题标题】:Why class size depend only on data members and not on member functions?为什么类大小只取决于数据成员而不取决于成员函数?
【发布时间】:2012-02-26 07:54:09
【问题描述】:

我想知道关于班级规模的详细说明。 我想知道是否只有数据成员和没有任何虚拟关键字的成员函数,那么为什么类大小只取决于数据成员。 例如:

class A {
    int a;
public:
    int display() { 
    cout << "A=" << a << endl;
   }
};

当我检查sizeof(A) 时,我发现它是 4 字节。为什么会这样?为什么成员函数对A类的大小没有影响?

谢谢

【问题讨论】:

标签: c++ class size


【解决方案1】:

因为类的函数没有保存在对象本身中。从 C 编程的角度来看,A 类的每个函数都有一个秘密参数,即 this 指针,因此实际上它们只是带有一个额外参数的函数。

例如想象它是这样的:

int display(A* thisptr)
{
   //do something
   printf("%d",thisptr->a); 
   return;
}

所以显示函数被保存为一个带有一个额外参数的简单函数。但名称会因编译器而异。

我相信不同的规则适用于涉及函数指针的虚函数,但由于我不确定其他人是否可以在这个问题上启发我们。

【讨论】:

  • 虚函数需要类的每个实例都包含一个指向“类定义”的指针,该指针指向适用于该类实例的虚函数版本
【解决方案2】:

这取决于实现 - 标准中未指定。但是,您是对的,非虚成员函数(甚至是第一个之后的虚函数)不会影响类的大小。

这是因为如果类的每个实例都有指向所有函数的指针,它将使用大量内存。他们为什么要这样做?在运行时,对象知道它是什么类型,它可以调用适当的函数。并且同一个函数在实例之间是相同的,不同的是它所操作的对象,它是作为参数传递的。

【讨论】:

    【解决方案3】:

    函数/方法存储为代码,而不是数据。就像一个可执行文件被存储为单个文件,并且可能被多次启动 - 它的多个实例将具有不同的数据。同样,函数是可执行代码,传递给它的数据可能不同(例如不同的文档,对于相同的文字处理软件)。

    可执行代码不会有任何sizeof,因为它们在程序运行时不会占用堆栈或堆空间。它本身存储在可执行映像中,并在您启动程序时由操作系统加载一次。

    【讨论】:

      【解决方案4】:

      就像普通的 C 函数一样,C++ 方法只是内存中的一个地址,用于在调用时跳转到执行。唯一的区别是第一个参数,它是一个指向调用函数的对象的指针。

      【讨论】:

        【解决方案5】:

        除了为实现虚函数和虚继承而引入的隐藏数据成员外,实例大小完全由类的数据成员和基类决定。来自 C++: Under the Hood (1994) 如果您想了解更多信息。

        【讨论】:

          【解决方案6】:

          成员函数是进程文本段的一部分,对象是进程数据段的一部分。因此,由于对象只是数据,它通过添加类的所有数据成员的大小来计算大小。成员函数对所有对象都是通用的,它的区别仅在于特定对象指针(称为 this 指针)的第一个参数,该指针作为隐藏指针传递给类的每个成员函数。

          【讨论】:

            【解决方案7】:

            因为函数状态留在堆栈中,并在函数进入/退出时被创建/删除。

            在对象的大小中,只有有助于存储对象状态的成员。函数只是从给定点开始的一段代码,不依赖于它所引用的特定对象实例。

            想想

            A a1, a2;
            

            a1.a 和 a2.a 不同,但是 a1.display() 和 a2.dispaly() 是同一个函数代码 (认为​​int A::display())为int display(A* this)

            【讨论】:

              猜你喜欢
              • 2020-03-16
              • 2013-05-03
              • 2019-10-11
              • 2015-10-04
              • 2017-02-22
              • 2021-06-25
              • 2017-03-25
              • 1970-01-01
              相关资源
              最近更新 更多