Class members and member functions memory location

Here be a simple C++ class:

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;
}

This is what I know so far:

  • when you declare an object of a class instance, memory gets allocated for that object. The allocated memory is equivalent to the memory of its members summed up. So in my case sizeof(A) = sizeof(int) = sizeof(m_a)
  • all member functions of class A are stored somewhere in memory and all instances of class A use the same member functions.
  • This is what I don't know:

    Where are member functions stored and how are they actually stored? Let's say that an int for example is stored on 4 bytes; i can imagine the RAM memory layout with 4 contiguous cells each storing a part of that int. How can I imagine this layout for a function?(this could sound silly, but I imagine functions must have a place in memory because you can have a pointer point to them). Also how and where are function instructions stored? My first perception was that functions and function instructions are stored in the program executable(and its dynamic or static libraries) but if this is true what happens when you create a function pointer? AFAIK function pointers point to locations in RAM memory, can they point to locations in program binaries? If yes, how does this work?

    Can anyone explain to me how this works and point out if what I know is right or wrong?


    First, you need to understand the role of the linker and what are executables (usually executed in virtual memory) and address spaces & processes. On Linux, read about ELF and the execve(2) syscall. Read also Levine's Linkers & Loaders book and Operating Systems: Three Easy Pieces.

    Member functions can be virtual or plain functions.

  • A plain (non virtual ) member function is just like a C function (except that it has this as an implicit, often first, parameter). For example your getA method is implemented like the following C function (outside of the object, eg in the code segment of the binary executable) :

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

    then imagine that the compiler is translating p->getA() into C$getA(p)

  • A virtual member function is generally implemented thru a vtable (virtual method table). An object with some virtual member functions (including destructor) has generally as its first (implicit) member field a pointer to such a table (generated elsewhere by the compiler). Your class A don't have any virtual method, but imagine if it had an additional virtual void print(std::ostream&); method, then your class A would have the same layout as

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

    and the virtual table might be

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

    (so adding other virtual functions means simply adding slot inside that vtable); and then a call like p->print(std::cout); would be translated almost like p->_vptr.print$fun(p,&std::cout); ... In addition, the compiler would generate as constant tables various virtual method tables (one per class).

  • NB: things are more complex with multiple or virtual inheritance.

    In both cases, member functions don't eat any additional space in the object. If it is non-virtual, it is just a plain function (in the code segment). If it is virtual, it shares a slot in the virtual method table.

    NB. If you compile with a recent GCC (ie with g++ ) you could pass it eg the -fdump-tree-all flag: it will produce hundreds of dump files showing partly -in a dumped textual form- some internal representations of the compiler, which you could inspect with a pager (eg less ) or a textual editor. You could also use MELT or look at the assembly code produced with g++ -S -fverbose-asm -O1 ....


    To understand this you need to learn about memory layout of a program. the code will be shared by the objects. and all objects will have their own copy of data.

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

    上一篇: 声明一个静态成员函数const或virtual

    下一篇: 类成员和成员函数的内存位置