Pergunta

I have two classes in C++:

class Base
{
  int baseField;
 public:
  Base();
  ~Base();
  T BaseMethod();
  virtual SomeMethod()=0;
};

class Derived : public Base
{
  int derivedField;
 public:
  Derived()
  ~Derived();
  T DerivedMethod();
  virtual SomeMethod() {...}; // Some implementation
};

My question is how it's represented in memory, i.e. where is this pointer, vptr (vtable) fields and methods pointers of this class. Ok, it's compiler dependent, but there is some unwritten standards. I'm most interested in Visual Studio and gcc compilers.

[Edit: I put one virtual method to improve example, there weren't any virtuals before]

Is there some books writing on this theme in details

Foi útil?

Solução

Your classes have no virtual table pointer since they have no virtual functions.

And like you said, even if they had, how virtual functions are implemented is not specified by C++ – every compiler can do it differently, there is no requirement for the existence of a vtable.

In practice, the sane implementation (for single inheritance) is to have a virtual table pointer at the beginning of the class, and after it the normal class members. There is no such thing as “method pointers” – normal member functions are resolved at compile time, and virtual functions have their pointers in the vtable in the order of their declaration.

Here’s an example layout:

struct Base {               + Base ------------+     + Base vtable ----+
    virtual void foo();     | * vptr        ---|---> | * void (*foo)() |
    T bases_field;          | * base_field     |     +-----------------+
};                          +------------------+

struct Derived {            + Derived ---------+     + Derived vtable -+
    T derived_field;        | * CBase instance |---> | * void (*foo)() |
};                          | * derived_field  |     +-----------------+
                            +------------------+

(Not to scale for bytes occupied in memory.)

Each instance thus contains a pointer to a virtual table. Per class, there is only one virtual table. I.e. one shared between all instances of CBase and one shared between all instances of CDerived.

Outras dicas

If the class contains at least one virtual function (yours doesn't) and does not use multiple inheritence (that gets complicated), the class usually contains a hidden pointer, to an array of function pointers to the virtual functions. This array is called the virtual function table and shared between all instances of the class. The fields are layed out in the same way as a C struct. The functions you provide are not stored inside the class. Their address is known by the linker, which inserts the call address when the functions are called. The this pointer is not stored inside the class. All non-static class functions, have the this pointer as a hidden parameter. This is pushed on the stack by whatever called the function on the class, which must know the object's address.

  • The this pointer is not stored. It is used to find the current object but there is no need to store it in the object.

  • Since you don't have any virtual method, there wont be any vptr table.

So in your example, you'll get something which is similar to a C struct with two fields.

Ok, it's compiler dependent, but there is some unwritten standards. I'm most interested in Visual Studio and gcc compilers.

It's not unwritten at all. Nor is it really compiler dependent. It is ABI dependent. That's a different thing.

MSVC is pretty much the only one to follow a convention not really documented externally, and even then, you could ask the Clang or MinGW developers.

GCC follows the Itanium ABI on most systems, and I believe that ARM has a specified ABI as well. These documents clearly specify what's going on in excruciating detail.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top