c++ - Must a pointer to an instance of class A be static in class B? -
ide: eclipse juno; compiler: mingw 4.6.2; project: win32
i have mainwindow 2 somewhat-dissimilar mdi child windows: mdichildwindowa , mdichildwindowb. third child window, sharedwindow, not mdi can used either mdi child window. encapsulated in own c++ classes.
to avoid proliferation of sharedwindow, borrowed part of singleton design: mainwindowclass::getsharedwindowinstance()
return pointer instance of sharedwindow, creating 1 if 1 doesn't exist. mainwindow.h
includes sharedwindow* psharedwindow
function. (that's close sharedwindow gets being singleton.)
when mainwindow instantiates mdichildwindowa , mdichildwindowb, passes this
constructors, save in class variable pmainwindow
(defined mainwindow*
in mdichildwindowa.h
, mdichildwindowb.h
).
cout
of this
in mainwindow matches cout
of pmainwindow
in mdi child window constructors, time function calls pmainwindow->getsharedwindowinstance()
, pmainwindow
has changed! making pmainwindow
static seems have solved problem but how did pmainwindow
change?
similarly, found hmodule
, lppicture
variables had static in sharedwindow.h
or forget values between functions in sharedwindow.cpp
. are pointer types somehow exempt persistence class variables? thought static
meant ensure 1 value across instances of class.
edit 2013-sep-04:
below application.cpp
(largely copied tutorial). thought mainwindow
instance created on heap , persist until exiting.
#include "mainwindow.h" int winapi winmain( hinstance hinstance, hinstance hprev, lpstr lpcmdline, int ncmdshow ) { msg msg; hwnd hmdiclientwindow; mainwindow *winmain = new mainwindow( hinstance ); if( !winmain->run( ncmdshow ) ) { delete winmain; return 1; } hmdiclientwindow = winmain->getmdiclientwindow(); while( getmessage( &msg, null, 0, 0 ) ) { if( ! translatemdisysaccel( hmdiclientwindow, &msg ) ) { translatemessage( &msg ); dispatchmessage ( &msg ); } } delete winmain; return msg.wparam; }
new mainwindow(...)
invokes mainwindow::mainwindow()
, cout
shows this
0xdd13a0.
mainwindow created in call run(...)
, passes pointer instance of mainwindow
in lpparam
:
bool mainwindow::run( int ncmdshow ) { ... hmainwindow = createwindowex( ..., ); ... }
in window procedure, pointer saved in instance data of mainwindow:
lresult callback mainwindow::mainwindowprocedure( hwnd hmainwindow, uint msg, wparam wparam, lparam lparam ) { mainwindow* pthis; if( msg == wm_nccreate ) { createstruct* pcreatestruct = (createstruct*) lparam; pthis = (mainwindow*) pcreatestruct->lpcreateparams; setwindowlongptr( hmainwindow, gwl_userdata, (long) pthis ); } else { pthis = (mainwindow*) getwindowlongptr( hmainwindow, gwl_userdata ); }
in wm_create
, cout
shows pthis
0xdd13a0 when it's passed constructors of mdichildwindowa , mdichildwindowb:
switch( msg ) { ... case wm_create: { unique_ptr<mdichildwindowa> upmdichildwindowa; unique_ptr<mdichildwindowb> upmdichildwindowb; ... up_mdichildwindowa = unique_ptr<mdichildwindowa>( new mdichildwindowa( m_hinstance, pthis, [window dimensions] ) ); up_mdichildwindowb = unique_ptr<mdichildwindowb>( new mdichildwindowb( m_hinstance, pthis, [window dimensions] ) );
the constructors of mdi child windows copy mainwindow
pointer in parameter pmainwindow
class variable m_pmainwindow
, , cout
shows both contain 0xdd13a0:
mdichildwindowa::mdichildwindowa( hinstance hinstance, mainwindow* pmainwindow, ... ) { m_pmainwindow = pmainwindow; .... }
in wm_create
of mdi child window procedure, cout
shows m_pmainwindow
still contains 0xdd13a0. other reference m_pmainwindow
occurs in wm_lbuttondblclick
where, unless i've made static, has somehow become 0xdd1380 (perhaps during pass through defmdichildproc(...)
?):
mdichildwindowa::mdichildwindowprocedure( ... ) { ... switch( ... ) { ... case wm_lbuttondblclick: { sharedwindow* psharedwindow; ... psharedwindow = pthis->m_pmainwindow->getinstanceofsharedwindow(); // pthis points instance of mdichildwindowa. cout confirms value hasn't changed.
since m_pmainwindow
pointing wrong place, program crashes when sharedwindow
function called via psharedwindow
. appears getinstanceofsharedwindow()
exists in bogus instance of mainwindow
because address returned - but, in code above, it's address of mdichildwindowa
!
(note: naming convention drives people nuts re-typed code less-dangerous names. there no typos.)
@brunocodutra, @chris hayes: don't have enough points comment yet, appreciate ideas.
hard tell without full relevant code, guess mainwindow being deallocated. further guess mainwindow originaly stored in stack, rather heap, because causes address change function call (which alters stack).
my advice: verify if either mainwindow or mdichildwindowa , mdichildwindowb (not sure pmainwindow changes) local variables , if so, change code, allocated in heap, i.e. dynamicaly through use of keyword new.
answering second question, pointers not treated differently other type, in essence integers, content promptly allowed interpreted memory addresses.
Comments
Post a Comment