vptr not created for derived class with its own virtual functions

This is a discussion on vptr not created for derived class with its own virtual functions within the C++ Programming forums, part of the General Programming Boards category; hi all, i'm new to C++ and i'm stuck at a very strange looking issue related to virtual functions of ...

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    5

    vptr not created for derived class with its own virtual functions

    hi all,

    i'm new to C++ and i'm stuck at a very strange looking issue related to virtual functions of derived class.

    I have code as below. During execution when putting breakpoint in last statement of main() function, i can see a vptr in (ptr to vtable) in base class obj b1 and same type of vptr in base class under object of derived class (d1) but i'm not able to see another exclusive vptr for derived obj d1 for func1(). Why??

    insert
    Code:
    #include "stdafx.h"
    #include <iostream>
    
    using namespace std;
    
    
    class base{
    public:
    	int nSize;
    	virtual void get();
    	virtual void set();
    };
    
    void base::get()
    {
    	cout << endl << "get() of base";
    }
    
    void base::set()
    {
    	cout << endl << "set() of base";
    }
    
    
    class der: public base
    {
    public:
    	char ch;
    	void get();  // override virtual base get()
    	virtual void func1();
    };
    
    void der::get()
    {
    	cout << endl << "get of der1";
    }
    
    void der::func()
    {
    	cout<< endl << "func of der";
    }
    
    int main()
    {
        base b1;
        der1 d1;
        
        b1.get();    // vptr suggest base::get() and base::set()
        
        d1.get();   // vptr is present under base part of d1 and suggest der1::get()
        d1.func(); // no vptr under d1, but still code executes.
    
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    First of all, this is C++, not "Tech Board" material. The errors:
    Code:
    class der: public base
    {
    public:
    	char ch;
    	void get();  // override virtual base get()
    	virtual void func1();
    };
    
    void der::get()
    {
    	cout << endl << "get of der1";
    }
    
    void der::func()
    {
    	cout<< endl << "func of der";
    }
    Note that the function names don't match. There's another error, but you'll see it as soon as you fix this and compile.

  3. #3
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,236
    In this particular case, the compiler knows the type of d1, and dispatches the call directly instead of going through the vtable.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,590
    Moved to C++ board. I believe this is the first time I have ever moved a thread from Tech to C++ - it is almost always the other way around.

  5. #5
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,236
    Quote Originally Posted by Bubba View Post
    Moved to C++ board. I believe this is the first time I have ever moved a thread from Tech to C++ - it is almost always the other way around.
    I thought it belonged in tech... The nature of the vtable is implementation-specific and definitely not a normal topic of discussion in standard C++...
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,295
    I believe this is a case of the compiler being smarter than you are. It knows that nothing derives from class 'der' and that is where 'func' was introduced into the heirarchy, therefore it is never possible to make a call to 'func' from an object of any other type, thus the v-table is unnecessary. It is perhaps easily able to work this out because this is all in one translation unit.

    At the end of the day, whether there is a virtual function table there or not does not matter.
    It is only important that the compiler must do the right thing according to the standard. How it does that is irrelevant. If the code performs correctly when run, then all is fine.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    Registered User
    Join Date
    Jan 2011
    Posts
    5
    Sorry for the typo errors.... as i pasted part of my code that i was testing.. hence forgot to do last minute checking.

  8. #8
    Registered User
    Join Date
    Jan 2011
    Posts
    5
    IMalc im not completely sure how compiler optimizes things, but i went by the book. i tried inheriting one more class from class der (say class der2: public der) and override func(), still didnt see exclusive vptr either for der part or der2 part of the object der2 d2. but i kind of agree to your answer here. thanks

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,295
    I'm not quite sure how the compiler does vtables, but it might just only have the one vtable and add a third entry to it, rather than creating multiple vtables for what is essentially a fairly simple scenario.

    You probably have to make sure that der2 is actually used, rather than just being defined.
    Did you make sure to call the overridden 'func' from a pointer to a 'der' too? I.e.:
    Code:
    der *x = new der2();
    der->func();
    Last edited by iMalc; 01-22-2011 at 01:32 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,208
    Apart from the need for additional entries, common sense suggests vtable structure will typically be determined by class structure (eg presence of virtual versus non-virtual bases in a multiple inheritence scenario). Among all compilers that implement a vtable (which most do, AFAIK), it is not "one vtable per virtual function".

    When code creates an instance of a class, the compiler has complete visibility of the corresponding class hierarchy. Otherwise the code cannot compile. The compiler therefore has all the information to specify how that class is laid out in memory, including layout of vtables (if any).

    The only requirement is that, for a given class, the compiler does things consistently between compilation units. As long as it meets that requirement, the compiler can pack things - more or less - as it likes and the packing scheme can be optimised for the target system. In that, the compiler is helped by the "one definition rule" - a programmer is not allowed to have code in distinct compilation units that creates two classes with the same name and different structure.
    Last edited by grumpy; 01-22-2011 at 03:12 PM.
    Right 98% of the time, and don't care about the other 3%.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Whats the best way to control a global class?
    By parad0x13 in forum C++ Programming
    Replies: 3
    Last Post: 11-12-2009, 04:17 PM
  2. overhead of virtual functions
    By coletek in forum C++ Programming
    Replies: 4
    Last Post: 01-12-2009, 11:56 AM
  3. Need help to build network class
    By weeb0 in forum C++ Programming
    Replies: 0
    Last Post: 02-01-2006, 10:33 AM
  4. C++ XML Class
    By edwardtisdale in forum C++ Programming
    Replies: 0
    Last Post: 12-10-2001, 10:14 PM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21