Class members and member functions memory location
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, and the C++11 standard n3337, and this draft report and a good C++ programming book, with this reference website.
Member functions can be virtual or plain functions.
A plain (non
virtual
) member function is just like a C function (except that it hasthis
as an implicit, often first, parameter). For example yourgetA
method is implemented like the following C function (outside of the object, e.g. 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()
intoC$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 additionalvirtual void print(std::ostream&);
method, then yourclass A
would have the same layout asstruct 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 likep->_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 (i.e. with g++
) or with a Clang (so clang++
) you could pass it e.g. 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 (e.g. less
) or a textual editor. You could also use MELT or look at the assembly code produced with g++ -S -fverbose-asm -O1
....