Large C++ classes
-
Saturday, August 18, 2012 7:20 AM
hey all,
Im still coding on a OPenGL FPS C++ game engine. Im now currentl using one class for the engine handling (window,opengl,sound loading,but not rendering, just loading). Is it bad for performance to use one enormous class rather than mutliple small ones?
another problem, since Im using this class, my game needs sth like 7 secs to start, while before using C-style global functions, it did already start like 1 sec. Does this has sth to do with that?
heres my class (some functions are defined outside, note its still rather incomplete):
/* CEngine declaration */
class CEngine
{
#ifdef _WIN32
HINSTANCE hInstance;
HWND hWnd;
HDC hDC;
HGLRC hRC;
MSG msg;
#else
#endif
// Functions called internallybool CSetupWindow();
bool CEnableOpenGL();
bool CEnableSound();
bool CSetupGUI();
bool CEnableSockets();static LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); // WndProc declaration
LRESULT CProcWindow(HWND,UINT,WPARAM,LPARAM);
public:
// Window management/input
bool key[256],init,lmouse,rmouse,focus;
unsigned short mx,my;
unsigned short width,height;
#ifdef _WIN32
void CToggleCursor(bool visible)
{
if (visible)
{
while (ShowCursor(true)<0)
{ShowCursor(true);}
}
else
{
while (ShowCursor(false)>=0)
{ShowCursor(false);}
}
}
void CResetCursor()
{
SetCursorPos(width/2,height/2);
}
void CDisplayState(unsigned short state)
{
ShowWindow(hWnd,state);
}
void CProcessMessage()
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
DWORD CGetTime()
{
return timeGetTime();
}
void CSwapBuffers()
{
SwapBuffers(hDC);
}
#else
#endif
// Server framework
bool update;
char master[INET6_ADDRSTRLEN]; // IPv6 and IPv4 support
// Engine state/properties
bool quit;
char rootpath[MAX_PATH];
unsigned short sample,vol,fov;
double sensitivity;
// Error report
char inerr[60];
char outerr[MAX_PATH];
// Constructor, deconstructer
#ifdef _WIN32
CEngine()
{
fov=STANDARDFOV;
focus=true;
width=GetSystemMetrics(SM_CXSCREEN);
height=GetSystemMetrics(SM_CYSCREEN);
GetCurrentDirectory(MAX_PATH,rootpath);
strcat(rootpath,"\\");
}
~CEngine()
{
BASS_Free();
if (hRC)
{
if (!wglMakeCurrent(NULL,NULL))
MessageBox(NULL,"Unable release the device context and rendering context.","Shutdown error",NULL);
if (!wglDeleteContext(hRC))
MessageBox(NULL,"Unable to release the rendering context.","Shutdown error",NULL);
hRC=NULL;
}
if (hDC&&!ReleaseDC(hWnd,hDC))
{
MessageBox(NULL,"Unable to release the device context.","Shutdown error",NULL);
hDC=NULL;
}
if (hWnd&&!DestroyWindow(hWnd))
{
MessageBox(NULL,"Unable to destroy the window.","Shutdown error",NULL);
hWnd=NULL;
}
if (hInstance&&!UnregisterClass(WNDNAME,hInstance))
{
MessageBox(NULL,"Unable to clear the window data.","Shutdown error",NULL);
hInstance=NULL;
}
}
#else
#endif
// Engine
bool CSetupEngine(HINSTANCE hInst) // Creates a fully functional window and engine
{
hInstance=hInst;
if (!CSetupWindow()||!CEnableOpenGL()||!CEnableSound()||!CSetupGUI()||!CEnableSockets())
return false;
return true;
}
// Sound
bool CLoadSound(char*,const unsigned short,bool=false);
void CStartSound(const unsigned short);
void CPauseSound(const unsigned short);
void CStopSound(const unsigned short);
void CSoundVol(const unsigned short);
// GUI
__forceinline void CPrintValue(const double,bool,double,double,const unsigned short);
__forceinline void CPrintText(const char*,double,double,const unsigned short);
void CScroll(double,double,double,double,double,const unsigned short);
void Inputbar(double,double,double,const double[3],const unsigned short);
void CPushbutton(const char*,double,double,const double[3],const unsigned short);
// OpenGL
bool CCheckExtension(const char*,const unsigned short);
void CResize(unsigned int,unsigned int);
void CRunResize(unsigned int,unsigned int);
bool CLoadBMP(const char*,unsigned int&,bool=false);
bool CLoadTGA(const char*,unsigned int&,bool=false);
// Model
bool CLoadModel(char*,const unsigned short);
};- Edited by DardanCPP Saturday, August 18, 2012 7:22 AM
All Replies
-
Saturday, August 18, 2012 2:51 PM
On 18/08/2012 09:20, DardanCPP wrote:
Im still coding on a OPenGL FPS C++ game engine. Im now currentl using one class for the engine handling (window,opengl,sound loading,but not rendering, just loading). Is it bad for performance to use one enormous class rather than mutliple small ones?
another problem, since Im using this class, my game needs sth like 7 secs to start, while before using C-style global functions, it did already start like 1 sec. Does this has sth to do with that?I believe you can write efficient code in C++ as well, without using pure C.
You may want to use some profiler to understand where the critical parts of your code are located, and try to optimize them.
Moreover, in general it's better to have (smaller) classes that do specific jobs instead of a "kitchen sink" huge class that tries to do everything. This is important to make code more readable, more maintainable, etc.
Embedding, composition and code reuse are good things.Giovanni
-
Saturday, August 18, 2012 4:54 PM
Why is it better to have smaller classes? Does this has to do with performance output of the compiler?
BTW how do you obtain or use a profiler?
-
Saturday, August 18, 2012 5:52 PM
The size of your classes has nothing to do with performance. Small classes that divide up the application into well-defined pieces of the app are a very big help to someone trying to learn and maintain the code. And if you come back to it in a year or so, that someone will be you :)
Nothing about your class partitioning could change the startup time from 1 to 7 secs. C++ might add a few percent in time. Not hundreds of percent!
- Proposed As Answer by BenoitRoosens Monday, August 20, 2012 6:29 AM
- Marked As Answer by Elegentin XieMicrosoft Contingent Staff, Moderator Tuesday, August 21, 2012 7:11 AM
-
Saturday, August 18, 2012 6:27 PM
Yeah man. You're all damn right. C++ is quick. I found using some sort of manual timer in code the culprit and I managed to get it. Thanks anyway for this!

