Jump to content
  • Advertisement
Sign in to follow this  
Xperience

Initialization Objects

This topic is 2136 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I have a simple question: Where should I initialize Objects?

From Rastertek tutorials: he use constructor to set members to their default value(like 0, nullptr etc.) and then he create bool function where he initialize members.

Should I do it the same way, or is here better approach?

Should object be ready to use after creation? 

I'll give a sample:(which approach is better or more usable?)

Window::Window() : m_HWND(nullptr)
{
	WNDCLASSEX wc;
	wc.cbSize = sizeof(wc);
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
	wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
	wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
	wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
	wc.hInstance = GetModuleHandle(nullptr);
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = L"GameWindow";
	wc.lpszMenuName = nullptr;
	wc.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;

	RegisterClassEx(&wc);

	m_HWND = CreateWindowEx(0, L"GameWindow", L"Billboard Tree", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
		WS_MINIMIZEBOX, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);

	ShowWindow(m_HWND, SW_SHOW);
	UpdateWindow(m_HWND);
}

Or this:

Window::Window() : m_HWND(nullptr)
{
	
}
bool InitializeWindow()
{
	WNDCLASSEX wc;
	wc.cbSize = sizeof(wc);
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
	wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
	wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
	wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
	wc.hInstance = GetModuleHandle(nullptr);
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = L"GameWindow";
	wc.lpszMenuName = nullptr;
	wc.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;

	if (!RegisterClassEx(&wc))
	return false;
	m_HWND = CreateWindowEx(0, L"GameWindow", L"Billboard Tree", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
		WS_MINIMIZEBOX, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);

	if (!m_HWND)
	return false;
	ShowWindow(m_HWND, SW_SHOW);
	UpdateWindow(m_HWND);

	return true;
}
Edited by Xperience

Share this post


Link to post
Share on other sites
Advertisement

Maybe not such an issue with a simple display class, but once your GUIs become any more complicated it can be a problem. With that said, generally your class should never ever be in an invalid state.

 

For Window to work like this there are a couple things to consider:

 

1) If Window is a member of, for example, an application class, you don't want it to automatically create a window just because you created an application instance. You want to have control over when the window itself is created on screen - perhaps you need to be able to load settings etc before creating it!

 

2) However, you don't want Window to be in an invalid state, so it is important that the Window instance has functionality to work even when a win32 window is not created. A function such as IsCreated is necessary, and internally there should be a mechanism to warn the user/error out/assert/something if you try to do stuff with a Window instance when a window is not created. It still won't feel completely solid, but it's not unheard of for GUI components.

 

3) The other possibility is to make it create the actual window in the Window constructor, and limit yourself to only have Window be a member in classes through use of a smart pointer (unique_ptr or shared_ptr usually). Now you can have the best of both worlds, code-wise, creating them only when you're ready and the object is always invalid (assuming no failure during window creation......).

 

Normally the problem is not so complicated. You simply create an object and it is valid. With resources such as GUIs and images/textures it can be a bit confusing to get right. It's also worth noting that in languages such as C# there are rules which make it much less natural to have invalid objects, and this seldom becomes a question because you usually have something that looks similar to #3.

Share this post


Link to post
Share on other sites

The biggest issue I am having with an initialization method is that it can be forgotten, which leads to uninitialized data which then leads to severe trauma to programmers that need to use that code and don't know there is an initialization method.

 

You can of course still make one and call it in the constructor so you will also have a "reset" method, but for the love of your programmers, make sure that when the constructor is called, all data is initialized! Think of the poor poor programmers!

Share this post


Link to post
Share on other sites

Personally I like to give objects a default constructor always and have the overloaded constructors simply be a convenient way to set startup data. An object shouldn't really do any creative behavior in it's constructor since that remove the option of delaying creation or setting special information on the object before calling a method on it.

 

Initialize methods are helpful but I treat them as a way to "reset" an object to default data, the constructor should always sets all variables to some value that won't crash the program or provide garbage information. Examples would be setting numbers to sensible values and insuring pointers are set to nullptr. In that sense the object is never in an "invalid" state, it just may not provide all behavior until you set certain dependencies.

 

Using that thinking you basically treat objects as "handles" to data and code and is reactive to your commands, promoting the black box idea.

Share this post


Link to post
Share on other sites

I have a simple question: Where should I initialize Objects?

It may seem a simple question but it is a rather complex answer.
 
Game objects are a bit different than GUI windows.
 
Being 'initialized' is a complex thing. Most large games have many versions of 'initialized'.  
 
Quoting myself from a topic last week on the matter:
 

There is the game object's basic default constructor.  This should generally do nothing. In cases such as serialization you are going to overwrite all the data inside the object anyway, so work in the constructor will be thrown away. That doesn't mean the object isn't fully created; think of it more like you could consider a file stream that hasn't been opened or otherwise attached to any resources.
 
There is a virtual function on game objects for when they are created. This might be used by world builders or when objects are created at run time. Do the initialization here. At this point it still should not be hooked up to any resources.
 
There is a virtual function on games objects for when they are started. This function is called after deserialization or creation. This might be after the level has loaded but before the game goes live to the player. This will also happen when objects are created at run time. Resources get requested here. Also hook up interactions and other components here.
 
There is a virtual function on game objects for when they are in the world. This lets the object hook itself up with other objects in the room or proximity. They might also set special flags such as requests to not be culled, or to set a non-standard culling distance. Some objects and triggers may not need to be placed in the world to be functional.
 
Many large games also have spatial culling. If so, there will likely be virtual functions when the object enters the simulated area and when they leave the simulated areas.
 
 
If all of those are true, there are several stages of initialization:  constructed --> created --> started --> in world --> visible.  It is possible to go back through the hierarchy as well, remove 'visible' when they are culled, remove 'in world' when they are removed from world, remove 'started' when the object is serialized or stopped for other reasons.

Share this post


Link to post
Share on other sites

I didn't mean exactly Windows GUI. I gave here a bad example. I meant a class like game entity, player, enemy etc. 

 

 

I have a simple question: Where should I initialize Objects?

It may seem a simple question but it is a rather complex answer.
 
Game objects are a bit different than GUI windows.
 
Being 'initialized' is a complex thing. Most large games have many versions of 'initialized'.  
 
Quoting myself from a topic last week on the matter:
 

There is the game object's basic default constructor.  This should generally do nothing. In cases such as serialization you are going to overwrite all the data inside the object anyway, so work in the constructor will be thrown away. That doesn't mean the object isn't fully created; think of it more like you could consider a file stream that hasn't been opened or otherwise attached to any resources.
 
There is a virtual function on game objects for when they are created. This might be used by world builders or when objects are created at run time. Do the initialization here. At this point it still should not be hooked up to any resources.
 
There is a virtual function on games objects for when they are started. This function is called after deserialization or creation. This might be after the level has loaded but before the game goes live to the player. This will also happen when objects are created at run time. Resources get requested here. Also hook up interactions and other components here.
 
There is a virtual function on game objects for when they are in the world. This lets the object hook itself up with other objects in the room or proximity. They might also set special flags such as requests to not be culled, or to set a non-standard culling distance. Some objects and triggers may not need to be placed in the world to be functional.
 
Many large games also have spatial culling. If so, there will likely be virtual functions when the object enters the simulated area and when they leave the simulated areas.
 
 
If all of those are true, there are several stages of initialization:  constructed --> created --> started --> in world --> visible.  It is possible to go back through the hierarchy as well, remove 'visible' when they are culled, remove 'in world' when they are removed from world, remove 'started' when the object is serialized or stopped for other reasons.

 

Thank's a lot, now I'm understanding principle about creating and initialization objects, but when we are talking about Window's GUI or DirectX GUI is it the same or?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!