If you don't want to read, the gist is that you need exceptions to return errors from ctors and exceptions are bad.
As Trevor and others have hinted at, there are a number of reasons for this practice. You've brought up a specific example here though, so let's address that.
The tutorial deals with a class GraphicsClass
(the name sure doesn't inspire confidence) which contains these definitions:
class GraphicsClass
{
public:
GraphicsClass();
~GraphicsClass();
bool Initialize(int, int, HWND);
void Shutdown();
};
So it has ctor, dtor, and Initialize/Shutdown
. Why not condense the latter into the former? The implementation gives a few clues:
bool GraphicsClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
{
bool result;
// Create the Direct3D object.
m_D3D = new D3DClass;
if(!m_D3D)
{
return false;
}
// Initialize the Direct3D object.
result = m_D3D->Initialize(screenWidth, screenHeight, VSYNC_ENABLED, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR);
if(!result)
{
MessageBox(hwnd, L"Could not initialize Direct3D", L"Error", MB_OK);
return false;
}
return true;
}
Ok sure, checking to see if new D3DClass
fails is pointless (it only happens if we run out of memory and we've overridden new
to not throw bad_alloc
)*. Checking to see D3DClass::Initialize()
fails may not be though. As its signature hints at, it's trying to initialise some resources related to graphics hardware, which can sometimes fail in normal circumstances - maybe the resolution requested is too high, or the resource is in use. We'd want to handle that gracefully, and we can't return errors in the ctor, we can only throw exceptions.
Which of course raises the question: why don't we throw exceptions? C++ exceptions are very slow. So slow that opinions of it are very strong, especially in game development. Plus you can't throw in the dtor, so have fun trying to say, put network resource termination there. Most, if not all, C++ games have been made with exceptions turned off.
That's the main reason anyway; I can't discount other, sometimes sillier, reasons though, such as having a C legacy (where there are no ctors/dtors), or an architecture that has pairs of modules A and B hold references to each other. Of course remember games development's #1 priority is to ship games, not create perfectly robust and maintainable architectures, so you sometimes see silly practices like this.
I hear that the C++ committee is deeply aware of the problems that exceptions have, but iirc the latest is that it's been put in the "too hard" bucket, so you'll see more of this in games for many years to come.
*- Aha! So checking to see if new D3DClass
wasn't pointless, as we've probably disabled exceptions so this is the only way to check for failed memory alloc, among other things.