类成员和成员函数的内存位置

这里是一个简单的C ++类:

class A
{
public:
    explicit A() : m_a(0) { }
    explicit A(int a) m_a(a) { }
    int getA() const { return m_a; }
    void setA(int a) { m_a = a; }

private:
    int m_a;
}

这是我迄今所知道的:

  • 当你声明一个类实例的对象时,会为该对象分配内存。 分配的内存相当于其成员的内存总结。 所以在我的情况下sizeof(A) = sizeof(int) = sizeof(m_a)
  • 类A的所有成员函数都存储在内存中,而类A的所有实例都使用相同的成员函数。
  • 这是我知道的:

    成员函数的存储位置以及实际存储方式? 假设一个int例如存储在4个字节上; 我可以想象RAM存储器布局与4个连续的单元格,每个单元格存储一部分int。 我怎么能想象这个布局的功能?(这听起来可能很愚蠢,但我认为函数必须在内存中占有一席之地,因为你可以有一个指针指向它们)。 还有如何以及在哪里存储功能指令? 我的第一个看法是函数和函数指令存储在程序可执行文件(及其动态或静态库)中,但是如果这是真的,那么创建函数指针时会发生什么? AFAIK函数指针指向RAM内存中的位置,它们可以指向程序二进制文件中的位置吗? 如果是的话,这是如何工作的?

    任何人都可以向我解释这是如何工作的,并指出我所知道的是对还是错?


    首先,您需要了解链接器的作用以及可执行文件(通常在虚拟内存中执行)以及地址空间和进程。 在Linux上,阅读ELF和execve(2)系统调用。 另请阅读Levine的连接器和装载机书籍和操作系统:三个简单的部分。

    成员函数可以是虚函数或普通函数。

  • 一个普通的(非virtual )成员函数就像一个C函数(除了其具有this作为一个隐式的,通常首先,参数)。 例如,您的getA方法像下面的C函数一样实现(在对象之外,例如在二进制可执行文件的代码段中):

    int C$getA(A*thisptr) const { return thisptr->m_a; }
    

    然后想象编译器正在将p->getA()转换为C$getA(p)

  • 虚拟成员函数通常通过vtable(虚拟方法表)来实现。 具有一些虚拟成员函数(包括析构函数)的对象通常作为其第一个(隐式)成员字段指向这样一个表(由编译器在别处生成)的指针。 你的class A没有任何虚拟方法,但想象一下,如果它有一个额外的virtual void print(std::ostream&); 方法,那么你的class A将具有相同的布局

    struct A$ {
       struct A$virtualmethodtable* _vptr;
       int m_a;
    };
    

    和虚拟表可能是

    struct A$virtualmethodtable {
      void (*print$fun) (struct A$*, std::ostream*);
    };
    

    (所以添加其他虚拟功能意味着只需在该vtable中添加插槽); 然后调用像p->print(std::cout); 将被翻译成几乎像p->_vptr.print$fun(p,&std::cout); ...另外,编译器会生成各种虚拟方法表(每个类一个)作为常量表。

  • 注意:事情比较复杂,多重或虚拟继承。

    在这两种情况下,成员函数都不会在对象中占用额外的空间。 如果它是非虚拟的,它只是一个普通的函数(在代码段中)。 如果它是虚拟的,它在虚拟方法表中共享一个插槽。

    NB。 如果使用最近的GCC编译(例如使用g++ ),则可以传递它,例如-fdump-tree-all标志:它将生成数百个转储文件,部分显示转储的文本格式 - 编译器的一些内部表示,其中您可以使用传呼机(例如less )或文本编辑器进行检查。 您也可以使用MELT或查看使用g++ -S -fverbose-asm -O1生成的汇编代码....


    为了理解这一点,你需要了解一个程序的内存布局。 代码将被对象共享。 所有对象都将拥有自己的数据副本。

    链接地址: http://www.djcxy.com/p/96359.html

    上一篇: Class members and member functions memory location

    下一篇: C++ Function pointer to member function of a static pointer object