Skip to main content
gamedev.net
🔒 Locked

C++ class methods

Started by GreG_K Sep 21, 2000 at 5:38 PM 5 replies 500+ views
Original Post
GreG_K
GreG_K
Hi! someone told me recently that each class method uses 2 pointers, why is this? and would it slow things down in the long run? Greg K.
Greg K.
felonius
felonius
2 pointers?!? Assuming you are talking about C++ then no way. That is wrong.

Instance methods use 1 pointer. Class methods uses 0.
Calling a class method is just as fast as calling a normal function not part of a class.

However, if you have exception handling activated some implementations might add an extra pointer, but 2? No.

Jacob Marner
Jacob Marner, M.Sc.Console Programmer, Deadline Games
Stoffel
Stoffel
They could have possibly meant the "this" pointer, implicit in all non-static class methods, and the vtable which is full of member function pointers.
mossmoss
mossmoss
quote:
Original post by GreG_K
Hi! someone told me recently that each class method uses 2 pointers, why is this? and would it slow things down in the long run?
Greg K.


Calling a class method involves zero pointers. Calling an instance method involves zero or one pointers.




---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!
Stoffel
Stoffel
Hm, the dangers of being self-taught:
1) You develop your own coding style (could be good, could be bad)
2) You completely lack the correct vocabulary.

I think #2 is getting me. So, if you all could help me out:

        
class C
{
public:
void funcA (); // what's this called?

static void funcB (); // and this?

virtual void funcC (); // pretty sure this is just called a virtual function

};

class D : public C { /* fill-in class */ };

int main ()
{
C::funcB (); // no pointers involved, yes?
C instance;
instance.funcA (); // pointer to instance used as this in funcA

C* pC = new D; // newD, get it? nyuk nyuk nyuk
pC->funcC (); // calles D->funcC through vtable, also a this pointer involved, 2 pointers, yes?
// rest of code politely frees pC, of course
}


So that shows all the pointers involved as I understand it. What would you "correctly" call funcA, funcB and funcC? I would call them a member function, static member function and virtual function, respectively, but I'm probably wrong.

Edited by - Stoffel on September 22, 2000 12:24:13 PM
null_pointer
null_pointer
Each class method uses 1 pointer, and that is the implicit pointer to the class''s instance (so that data and class methods can be used inside the function).

If you are a C programmer, these two are very similar (should compile to identical assembly):


// in C
typedef struct _tagPOINT {
short x;
short y;
} POINT;

do_something(POINT* the_point) { /* add code */ }

// in C++
struct point
{
short x;
short y;

do_something() { /* has access to instance''s x and y */ }
};



That happens because the pointer passes a hidden argument (a pointer to the class instance) in a C++ class member function. That hidden argument is called "this" (which makes sense if you think about it). You can use "this" in your code if you want to, or just use the member variable names as if they were local to the function.

The following two functions are identical to the compiler:


class point
{
short x;
short y;

do_something() { x=0; y=0; }
do_something_else() { this->x = 0; this->y = 0; }



About virtual functions (GreG_K, you can ignore this if you want to):

The vtbl (short for Virtual Function TaBLe) is basically an array of pointers to functions. This is how the compiler implements virtual functions. Virtual functions are called through a layer of indirection (pointer). When derived classes are made that "override" the virtual function, the function pointer is updated by the compiler and the correct version is called.

There is only one vtbl per class; each instance contains a 4-byte pointer to the vtbl, and that pointer is called lpvtbl (short for obsolete-name Pointer to a Virtual Function TaBLe).

To maintain good performance, a vtbl is not created, and thus there is no per-instance overhead for a lpvtbl (the pointer, remember), unless you actually add a virtual function to the class.

If you are in doubt, place the following code in a console app in MSVC, step through it, and browse the data members of the class in the Variables window (while debugging):


class simple
{
public:
simple() { x=0; }

int x;
};

class more_complex
{
public:
more_complex() { x=0; }
virtual ~more_complex() {} // aha! a virtual function

int x;
};

class most_complex
{
public:
most_complex() { x=0; }
virtual ~more_complex() {} // first virtual function

virtual void start() {}; // second...
virtual void stop() {}; // third virtual function...

int x;
};

#include &ltiostream>
using namespace std;

// now just use sizeof() to get the size of the classes
int main(int, char*)
{
cout << "The size of simple is: " << sizeof(simple) << endl;
cout << "The size of more_complex is: " << sizeof(more_complex) << endl;
cout << "The size of most_complex is: " << sizeof(most_complex) << endl;
}



The size of the simple class should be 4 bytes, the size of the more_complex class should be 8 bytes, and the size of the most_complex class should be 8 bytes too.

Naturally, this means that you don''t want to go putting virtual functions in small classes where you''ll be using 10,000 or 100,000 instances quite frequently, because the extra 4 bytes per instance could kill you. In large classes that are not used in such quantity, virtual functions could be of benefit.

Just know when to use it, and it will serve you well.



- null_pointer
Sabre Multimedia

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.