Advertisement

member variable initialization in the header...or not? :S

Started by July 18, 2017 08:03 AM
11 comments, last by MarcusAseth 7 years, 4 months ago

Here's my dilemma, I have this bunch of variable inside a class


protected:
	//Window
	HINSTANCE mhAppInstance{};
	HWND mhWindow{};
	std::string mWindowCaption{};
	UINT32 mClientWidth{};
	UINT32 mClientHeight{};
	bool mWindowed{};
	bool mMinimized{};
	bool mMaximized{};
	bool mResizing{};
	
	//Timer
	GameTimer mTimer{};
	bool mAppPaused{};

	//D3D 
	D3D_DRIVER_TYPE mDriverType{};
	ID3D11Device* mDevice{};
	ID3D11DeviceContext* mImmediateContext{};
	IDXGISwapChain* mSwapChain{};
	ID3D11Texture2D* mDepthStencilBuffer{};
	ID3D11RenderTargetView* mRenderTargetView{};
	ID3D11DepthStencilView* mDepthStencilView{};
	D3D11_VIEWPORT mScreenViewport{};
	
	//D3D Settings
	bool mEnable4xMsaa{};
	UINT m4xMsaaQuality{};

and I have all 0 initiazed them trough curly brackets, but now I was thinking to take it a step further and write inside the  curly brackets the initial state of my bools.

To me this seems perfect because I have a huge list of variables with all their starting states as soon as I open the header page without need to scroll up and down if I where to initialize them inside the cpp, so flipping pages is faster than scroll up and down (at least for me)...but despite this convenience that seems obvious to me, It seems like everyone go and initialize their variable in the constructor.

So I was wondering, I am doing it wrong and there are serious concerns and reason I should know about for not doing it in the way I am or is just a stylistic choice? (I don't think it is since too many people seems doing it that way...)

:)

Initializing variables like that is only possible from C++11 and onwards. This might explain why you haven't seen it a lot.

There are times where it might be useful (if the variables should always be the same thing, i.e. not default to different things in different constructors/circumstances, etc.), and times were you cannot use it (depends on variables passed in, etc.).

Some more information about this here:

https://stackoverflow.com/questions/28413154/c-initializing-variables-in-header-vs-with-constructor

Hello to all my stalkers.

Advertisement

I see. Christian Hackl in that link mention possible expensive recompilations if one where to change the initial value of a variable specified in a header file, so my super noob question is, there is a way for me inside Visual Studio 2017 to track this recompilation time so that I can do my experiments and just be aware of it? :S

Edit: oh wait, I can actually google that myself xD Pretty sure is a easy to find one

If you have the initialization in the header, every file that includes that header will have to be recompiled if you change the value. 

As for tracking it, just hit compile and see how long it takes.

Hello to all my stalkers.

Apparently I had the compile time turned off by default (default VS2017 setting), according to Peter Mortensen  the procedure to show it is 

Menu Tools  Options  Projects and Solutions  VC++ Project Settings  Build Timing 

Nice! :D

Small followup, after long reasoning I might have discovered my style for initializing the varibles in a header, and I may also discovered that I have some OCD problems :D

Rules:

1)Variable names line up under each section, same for the initialization brackets

2) 1 space between the longest type name of a section(marked by a comment) and variable name

3) only nullptr and true/false allowed inside brackets(for now, this may change)

4)initialization brackets line up based on the longest variable name


protected:
	//Window
	HINSTANCE    mhAppInstance { nullptr };
	HWND	     mhWindow	   { nullptr };
	std::string  mWindowCaption{};
	UINT32       mClientWidth  {};
	UINT32       mClientHeight {};
	bool         mWindowed	   { true }; //CARE: at the moment we are not actually changing this when not windowed
	bool         mMinimized	   { false };
	bool         mMaximized	   { false };
	bool         mResizing	   { false };

	//Timer
	GameTimer  mTimer    {};
	bool       mAppPaused{ false };

	//D3D 
	ID3D11Device*		mDevice		   { nullptr };
	ID3D11DeviceContext*    mImmediateContext  { nullptr };
	IDXGISwapChain*         mSwapChain	   { nullptr };
	ID3D11Texture2D*	mDepthStencilBuffer{ nullptr };
	ID3D11RenderTargetView* mRenderTargetView  { nullptr };
	ID3D11DepthStencilView* mDepthStencilView  { nullptr };
	D3D11_VIEWPORT	        mScreenViewport    {};

	//D3D Settings
	bool mEnable4xMsaa  { true };
	UINT m4xMsaaQuality {};

 

Advertisement

Note that the initialization has a cost. It is small, but it exists.  You can often do the initialization at the same cost -- and possibly at a lower cost -- with your constructor.

 

Why do you need to initialize mWindowCaption? It is a std::string, it comes properly initialized to empty all by itself. 

Are there items on that list that are initialized or set to specific values at other times? For example, you probably are setting the application pointer, the width and height, and a few other D3D values immediately after construction. Why do you blank those out and pay the cost of assigning to them twice?  If proper usage requires you to set them to a value before they are otherwise used, initializing them to a value such as zero or null and then immediately writing to them a second time with the expected value is wasteful. 

My only argument would be that I'm not confident enough I'll remember to initialize everything and I always assume I will fuck up so I just want a second line of defense by just putting { } in front of every variable I declare and not have to think about it anymore. 

But is a weak argument I know :P

 

Quote

You can often do the initialization at the same cost -- and possibly at a lower cost -- with your constructor.

You mean before the constructor body like


A::A(int value) : variable(value)  // <---this on the left
{

}

or inside the constructor body? Or is the same thing? :S

That means with the constructor initializer list. That is the constructorname : variable(value) thing you've got up there.  Be certain they are in the same order as they exist in the class.  

Initializing them inside the body takes place after the others, so putting it in the body also incurs the cost of multiple initializations for types that have initializers/constructors.

Initializing them the way you are doing it now does have the benefit of ensuring a value is assigned, at the risk of potentially paying the cost multiple times.  If you're fine with the cost and don't trust yourself, what you've got can work.  

That's useful information :P

By the way, I'm pretty sure I won't stick with this way of initializate things for long, I will grow past it pretty soon, :D  performance first.

This topic is closed to new replies.

Advertisement