c++ oo syntax behind the scenes behavior

Started by
21 comments, last by King Mir 10 years ago

if i declare a class, then declare an instance of that class, when is the instance allocated on the heap (assuming it has member variables) ?

where is the VMT stored, and when ?

and there's just one VMT per class, right?

non virtual method calls require no vmt lookup, correct?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement

if i declare a class, then declare an instance of that class, when is the instance allocated on the heap (assuming it has member variables)?

The instance is allocated on the heap when you call new (or malloc() or another similar func). No sooner, no later.

where is the VMT stored, and when ?

With the memory of the class, when the class is created - usually alongside the member variables in memory. Sorry, not thinking clearly. The pointer to the v-table is stored alongside the member variables (because it is a member variable - just a hidden one added by the compiler).

and there's just one VMT per class, right?

One VMT per class instance, yes.

[Edit:] I forgot about multiple inheritance. One VMT for each base class in each instance.


class Derived : BaseA, BaseB

One v-table for BaseA, one for BaseB.

[Edit 2:] Wow, really not thinking straight today. Read TheComet's post below. happy.png Each class definition will have it's own v-table, but each class instance just has a unique pointer to a v-table. BaseA and BaseB each have a pointer to a v-table. BaseA points to BaseA's v-table, but Derived inherits that pointer and changes it to point to Derived's custom BaseA v-table. BaseB has a pointer to BaseB's v-table, but Derived inherits that and changes the value to point to Derived's custom BaseB v-table.

non virtual method calls require no vmt lookup, correct?

Yes. And if the class itself has zero virtual functions, then it won't have any Virtual Method Table.

Wikipedia gives some examples here.

When you define/instantiate an instance of a class using the new operator, sizeof(ClassName) number of bytes are allocated on the heap, and a pointer pointing to the beginning of the instance is returned.


ClassName* instance = new ClassName(); // memory is allocated on the heap here
instance->doSomething();

When you define/instantiate an instance of a class on the stack, the memory is guaranteed to be allocated when you need it.


ClassName instance; // Memory is allocated on the stack here
instance.doSomething();

The VMT is typically stored by adding an extra private pointer member variable to the class, which points to a virtual table. Every instance of the class generally shares the same virtual table.

If you add more virtual functions, the class size does not grow though.

This can be shown with the following code:


#include <iostream>

class Foo
{
public:
    Foo() {}
    virtual ~Foo() {}
private:
    int a;
};

class Bar
{
public:
    Bar() {}
    virtual ~Bar() {}
    virtual void set( int a ) { this->a = a; }
    virtual int get( int a ) { return a; }
private:
    int a;
};

int main()
{
    std::cout << "sizeof(Foo): " << sizeof(Foo) << std::endl;
    std::cout << "sizeof(Bar): " << sizeof(Bar) << std::endl;

    return 0;
}

Foo and Bar have the same size, even though Bar has more virtual functions.

"I would try to find halo source code by bungie best fps engine ever created, u see why call of duty loses speed due to its detail." -- GettingNifty

where is the VMT stored, and when ?

With the memory of the class, when the class is created - usually alongside the member variables in memory.

I think you're confusing a pointer to the vtable and the vtable itself. An object will store a pointer to the vtable not the full table. The vtables themselves are generally stored in a read only data segment.


If you add more virtual functions, the class size does not grow though.

That can be a little misleading. The size of objects (class instances) does not grow, but the vtable size changes, and maybe even its layout changes. That's important to know, because it's an ABI change and the not infrequent cause of subtle and inexplicable runtime failures.

This sort of thing shows up as a problem if, for example, you add a virtual function to a header file and rebuild a program, but do not rebuild a DLL that also uses the header file. Bam!

Stephen M. Webb
Professional Free Software Developer

I think you're confusing a pointer to the vtable and the vtable itself. An object will store a pointer to the vtable not the full table. The vtables themselves are generally stored in a read only data segment.

Yep, already edited my post. I should remember to hold off on posting in the morning until after breakfast. laugh.png


The instance is allocated on the heap when you call new (or malloc() or another similar func). No sooner, no later.

what about something like:

class myclass
etc
 
 
 
void main
{
myclass object1;   // declare an instance of a myclass object called object1
etc
}
 

note that my syntax may be off a bit there, but i think you get the type of declaration i'm talking about.

that would get allocated when main was called, right?

but something like....

 
class myclass
etc
 
myclass object1;   // declare an instance of a myclass object called object1, global to everything that follows in the module.
 
 
void main
{
etc
}
 

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


When you define/instantiate an instance of a class on the stack, the memory is guaranteed to be allocated when you need it.
ClassName instance; // Memory is allocated on the stack here
instance.doSomething();

fascinating! i thought local declarations did a new in the background and a dispose on return, using the heap.

so locally declared objects go on the stack. that would imply no memory leaks possible, correct?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


This sort of thing shows up as a problem if, for example, you add a virtual function to a header file and rebuild a program, but do not rebuild a DLL that also uses the header file. Bam!

the classic code and header out of sync explosion!

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

based on the above posts, given:

 
class myclass
etc
 
void main
{
myclass object1;
}
 

would object1 go on the stack when main was called? or is main a special case and it goes in the data segment?

also, i takes it that given:

 
class myclass
etc
 
myclass object1;  // global to code that follows in this module
 
void main
{
etc
}
 
 

object1 (its member var storage space) would go in the data segment?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

This topic is closed to new replies.

Advertisement