   Strange behaviour of virtual functions
  I just found a very strange behaviour in 2 of my GUI classes.I have a CIElement class, wich is the base class for all gui elements. It will test wether it is hovered or can be dragged etc...But because some controls won't always allow dragging or hovering, the functions CheckHover and CheckDrag are declared virtual in CIElement.My 2nd class, CWindow is derrivated from CIElement and overwrites these 2 functions.The decaration lies within Window.h, their bodys in Window.cpp.Since these functions do have many protected and private functions, that use or return classes, that don't need to be known by any user of CWindow, I put a #ifdef _WINDOW_CPP around these declarations (because any code that would want to work with CWindow would also need to know the declarations of any used class / struct in the private functions => a lot more compile time), to exclude them from any other file than Window.cpp (wich obviously defines _WINDOW_CPP).However, if I do this, the overwritten functions CheckHover and CheckDrag won't be called from within CIElement. So CheckHover() will only call the function from CIElement, but not from CWindow, although it should.Why is that?   
  I'm confused - can we see some code?It sounds to me like two modules are seeing two different prototypes for the class, and the vtable is getting screwed up. Window.cpp thinks there's 2 more functions in there than other modules think, and the wring vtable entries are probably beign accessed. Have you tried seeing if the previous or next virtual functions are called instead of CheckHover and CheckDrag?I'd recommend just removing the #ifdef from the header, it seems unnessecary.   ;  ofcourse you can://IElement.hclass __declspec( dllexport ) CIElement{public:virtual bool CheckHover( D3DXVECTOR2 mousepos, D3DXVECTOR2 absolut );virtual bool CheckDrag( D3DXVECTOR2 mousepos, D3DXVECTOR2 absolut );};//Window.hclass __declspec( dllexport ) CWindow : public CIElement{public:...protected:#ifdef _WINDOW_CPPCCaption *GetCaption();void Draw( D3DXVECTOR2 parent, border_types type );bool CheckHover( D3DXVECTOR2 mousepos, D3DXVECTOR2 absolut );bool CheckDrag( D3DXVECTOR2 mousepos, D3DXVECTOR2 absolut );#endif};//Window.cpp#define _WINDOW_CPP#include "IElement.h"#include "Window.h"From Withing CIElement, I try to call CheckHover. It should call CWindow::CheckHover, but instead it only calls CIElement::CheckHover.I did now remove the ifdef, because this way dragging the window works, but I'm just curious why.   ;  It sounds likeYou're violating the One Definition Rule:Quote:Herb Sutter:Your program can compile more than one definition of the same function or class in different places in the program and happily link them all together and that’s perfectly legal, as long as all those definitions are exactly identical.As Evil Steve says, theis could very well be caused by your compiler laying out the vtable differently for the different definitions.Another point to note is that the symbol _WINDOW_CPP is reserved as it begins with and underscore followed by a capital letter, so this could also cause problems (it's quite possible that some microsoft code somewhere defines _WINDOW_CPP although, from your description of the problem, an ODR violation seems most likely).   ;  Interesting. Ignore what I said in my previous post, if the function is virtual in the base class, and it's not #ifdef'd there, it'll be fine. It's still not a particularly good idea though [smile]The only reason what you're seeing should happen is if the CWindow constructor doesn't set up the vtable correctly; which should only happen if the CWindow class doesn't know that it has as CheckHover or CheckDrag function - which obviously doesn't make sense.So - I've no idea [smile]   ;  Just... no.Remove the ifdefs and your virtual function problems should go away. If you still want to prevent users of Window having additional dependancies then define an IWindow interface which only exposes what they need to know and let your window class inherit from it.   ;  Are you defining constructors for those two classes, or are you using the compiler generated default constructors?Also, are any of your constructors defined in the header?   ;Quote:Original post by NitageAre you defining constructors for those two classes, or are you using the compiler generated default constructors?I did define several constructors for the two classes, no default ones.They are not defined withing the header. Their definition lies within the cpp file.Quote:Original post by OrangyTangRemove the ifdefs and your virtual function problems should go away. If you still want to prevent users of Window having additional dependancies then define an IWindow interface which only exposes what they need to know and let your window class inherit from it.I'm not shure what you have in mind. Should CWindow be derrivate from CIElement and IWindow?   ;  ... Could the objects be getting sliced? (You need to go through a reference or pointer to get at virtual functionality; and copying into an element of the base type - including via passing a parameter by value - loses the derived-type information, at best.)   ;Quote:Original post by SiS-ShadowmanQuote:Original post by OrangyTangRemove the ifdefs and your virtual function problems should go away. If you still want to prevent users of Window having additional dependancies then define an IWindow interface which only exposes what they need to know and let your window class inherit from it.I'm not shure what you have in mind. Should CWindow be derrivate from CIElement and IWindow?Yes. Derive Window from IWindow and CIElement, then replace usages of Window with IWindow. That'll remove the dependancies without any kind of crazy preprocessor hacks.   