[fixed. Thank you Kippesoep] C++ static member variable and inheritance problem
I have a base class CWindow, and two inherited class from it. In the CWindow class, I have a public static member variable ( bool isValid) that I want to be false at the beginning, but changed to true after one instance of the inherited window is initialized.
However, isValid changes to false each time I initialize a derived class object.
At the beginning of the CWindow.cpp file, I defined the initial value of isValid:
bool CWindow::isValid = false;
Every time I use this variable in the program, I use:
CWindow::isValid = true
or
if ( !CWindow::isValid ) {
}
What could be wrong?
[Edited by - xinvar on July 29, 2005 2:13:20 PM]
Not sure exactly what's wrong, but this should be all you need:
This takes into account your statement that you want isValid to change to true only when a derived class is instantiated. If CWindow itself cannot be instantiated and you have no other derived classes that satisfy this condition, it would be:
/* CWindow.h */class CWindow{public: CWindow (); virtual ~CWindow (); static bool isValid;};/* CDerived1.h */#include "CWindow.h"class CDerived1 : public CWindow{public: CDerived1 (); ~CDerived1;};//analogous for CDerived2/* CWindow.cpp */bool CWindow::isValid = false;CWindow::CWindow (){ //Don't do anything to isValid here}CWindow::~CWindow (){ //Nor here}/* CDerived1.cpp */CDerived1::CDerived1 (){ //Set the variable isValid = true;}CDerived1::~CDerived1 (){ //Leave isValid alone}/* CDerived2.cpp analogous to CDerived1.cpp */
This takes into account your statement that you want isValid to change to true only when a derived class is instantiated. If CWindow itself cannot be instantiated and you have no other derived classes that satisfy this condition, it would be:
/* CWindow.h */class CWindow{public: CWindow (); virtual ~CWindow (); static bool isValid;};/* CDerived1.h */#include "CWindow.h"class CDerived1 : public CWindow{public: CDerived1 (); ~CDerived1;};//analogous for CDerived2/* CWindow.cpp */bool CWindow::isValid = false;CWindow::CWindow (){ //Set the variable isValid = true;}CWindow::~CWindow (){ //Nor here}/* CDerived1.cpp */CDerived1::CDerived1 (){ //Don't do anything to isValid here}CDerived1::~CDerived1 (){ //Leave isValid alone}/* CDerived2.cpp analogous to CDerived1.cpp */
in each of your derive class constructor do CWindow::isValid = true; now as long as nothing else modify it then it should remain true, then when you call CWindow::isValid it should return true.
thank you very much Kippesoep and nhatkthanh. But why do I need to initialize it in all the derived class? I thought static member variables would just stay in the memory, and once you initialize it:
/* CWindow.cpp */
bool CWindow::isValid = false;
It'll be false until we change it somewhere else -- in my case, it'll be in CDerived1::CDerived1(). And once we change it in CDerived1::CDerived1() to be TRUE, it'll be true unless I change it again somewhere else.
/* CWindow.cpp */
bool CWindow::isValid = false;
It'll be false until we change it somewhere else -- in my case, it'll be in CDerived1::CDerived1(). And once we change it in CDerived1::CDerived1() to be TRUE, it'll be true unless I change it again somewhere else.
Sorry for messed things up. Let me be more clear on my problem:
In CWindow::OnCreate() I would initialize the window, and if successful, set: CWindow::isValid = true. (I debugged into the program, it's always successful)
CDerived1 and CDerived simply use CWindow::OnCreate() (no overloaded function defined in CDerived*).
isValid controls something that I ONLY want to initialize ONCE for my program. I have two instances of CDerived1 and 3 instances of CDerived2 (splitted windows), and isValid should be true after ANYONE of the 5 instances gets created, so that the init stuff in
if ( !isValid ) {
}
only runs once.
But isValid turns false for at init of each of the 5 instances.
In CWindow::OnCreate() I would initialize the window, and if successful, set: CWindow::isValid = true. (I debugged into the program, it's always successful)
CDerived1 and CDerived simply use CWindow::OnCreate() (no overloaded function defined in CDerived*).
isValid controls something that I ONLY want to initialize ONCE for my program. I have two instances of CDerived1 and 3 instances of CDerived2 (splitted windows), and isValid should be true after ANYONE of the 5 instances gets created, so that the init stuff in
if ( !isValid ) {
}
only runs once.
But isValid turns false for at init of each of the 5 instances.
Ah, that makes a bit more sense. In that case, simply have "isValid = true" in the OnCreate handler. Nowhere else. If it does change it's value other than by that direct code, you have a bug. A common mistake is:
Could also be a memory error elsewhere in your program.
if (isValid = false) //should be "=="
Could also be a memory error elsewhere in your program.
it is a common bug.. but actually in my program i used:
if ( ! COpenGL_Window::m_bHRCValid ) {
...
COpenGL_Window::m_bHRCValid = true;
}
A memory error SOMEWHERE ELSE.... that's really tough.
if ( ! COpenGL_Window::m_bHRCValid ) {
...
COpenGL_Window::m_bHRCValid = true;
}
A memory error SOMEWHERE ELSE.... that's really tough.
Quote:Original post by xinvar
A memory error SOMEWHERE ELSE.... that's really tough.
Yes, but there are ways to find it more easily, especially if your development environment supports memory/data breakpoints. If you're using Visual Studio, press Alt-F9 to bring up the breakpoint window. Create a new data breakpoint with the expression "COpenGL_Window::m_bHRCValid". Whenever the value of that variable changes, the program will break into the debugger.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement