Initialization and Constructors

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
User avatar
Zedtho
Posts: 189
Joined: February 14th, 2017, 7:32 pm

Initialization and Constructors

Post by Zedtho » March 5th, 2017, 1:02 pm

I've got a few questions:

First of all, when initializing variables you can do the following:

1:
int x;
x = 5;

2:
int x {5};

3:
int x = {5};

4:
int x = 5;

I know that 2 and 3 are the same thing, and that 1 isn't always used because I could use the variable before initializing it, giving me bad output.
But why use the {} when I can just do 4?


Next up with classes (specifically constructors)
For example:
1:
Game::Game(int Initializer0, int Initializer1)
:SomeVar{Initializer0}, SomeOtherVar{Initializer1}
{

}

2:
Game::Game(int Initializer0, int Initializer1)
{
SomeVar = Initializer0;
SomeOtherVar = Initializer1;
}


Apparently there's no difference...
My main question is what the Game::Game():
does. I mean the : after Game::Game().

Nonetheless thanks for reading this and helping the newcomers!

User avatar
Battlefrog
Posts: 69
Joined: March 31st, 2015, 10:10 pm
Location: Florida, United States of America

Re: Initialization and Constructors

Post by Battlefrog » March 5th, 2017, 5:27 pm

bump.

I NEED ANSWERS!
Broc W.

Sole Member of Sledgehog Software, trademark and LLC status pending.

User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: Initialization and Constructors

Post by chili » March 6th, 2017, 1:32 am

Let's see, main diff between () and {} is {} does not allow shit to be implicitly converted. So if you have a constructor that takes float, Thing( 69 ) will work but Thing{ 69 } will not work (need Thing{ 69.0f }).

For this reason some people prefer brace-init {} because it is stricter. Also, you can only init POD aggregrates that have no constructor defined with the brace init I believe.

Game::Game() : ....
What this does is call the constructor of an embedded object wit hthe params. Using = in the function body can sometimes be wasteful (depends on situation) cuz basically you're calling the default constructor, than you]re calling the assignment operator.

Also, for shit whith no default constructor, you need to do the member init list (Constructor() : ...).
Chili

User avatar
Zedtho
Posts: 189
Joined: February 14th, 2017, 7:32 pm

Re: Initialization and Constructors

Post by Zedtho » March 6th, 2017, 10:16 am

Thanks a lot for answering this!

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Initialization and Constructors

Post by albinopapa » March 6th, 2017, 10:18 am

Shoot man, for vars that I don't need right away I init with {} just empty braces instead of var = 0;, it does the same thing, but I just like the way it looks. Plus with structs or classes, you can init with empty braces to init the entire object to 0 instead of having to call memset or the WinAPI ZeroMemory to make all members 0.

struct Foo
{
int varInt;
float varFloat;
};

Foo foo{}; // Now foo.varInt and foo.varFloat are 0 and 0.f

As chili stated, data types of POD ( plain ole data ) can also be initialized using {}
Foo foo{42, 3.141592f};
Though I like
Foo foo = {42, 3.141592f};

The constructor of a class has two parts, the initializer list and the function body. The initializer list does just that, initializes members of the class. Once the initializer list has been run, the function body is called and anything in there would be assigned. And as chili states, could be an issue. Take the Game constructor as an example. It doesn't have a default constructor, nor does Graphics. Since they don't have default constructors to call, they can't be initialized unless you use the initializer list of Game::Game.

That brings up a "rule of thumb" as they say, prefer initialization over assignment. Always initialize your variables to a value, instead of declaring them then assigning them later on. Plus, you can use more const variables this way. I want to say that the compiler can perform some optimizations in these cases because once a const variable is read, the compiler knows the value won't change from read to read, so won't have to reload that data each time.

Though as a side note, one thing I've noticed over the past couple of weeks is there is only so much you can do to for optimizations before you just go, "You know what? There are so many instructions here, a non const here or there isn't going to speed things up anyway." As a matter of fact, all the optimizations techniques I have tested have provide little to no performance boost.

You find yourself looking to things like SSE/AVX and multi-threading. Then when you max those out, you still want more speed so you look into GPGPU processing ( C++ Amp, OpenCL, CUDA, DirectCompute ).

I know stupid rant.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

User avatar
Zedtho
Posts: 189
Joined: February 14th, 2017, 7:32 pm

Re: Initialization and Constructors

Post by Zedtho » March 6th, 2017, 10:57 am

Very interesting!
I heard that people like
int Variable = {};
because it used to be like that?
I don't exactly know.
Also, is there a value you can initialize something with that then gets displayed as an error value, unless something sets it to something different later?
So that I know that it hasn't been initialized when debugging.
I heard something of NULL once, I don't know for sure, though.

Tell me if I should clarify, since I don't have the time to elaborate currently.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Initialization and Constructors

Post by albinopapa » March 6th, 2017, 9:12 pm

The ( int var = {}; ) is how you HAVE to do it in C, but in C++ you can leave out the = or at least you can since VS 2012, I didn't know about it when I started programming and was using VS 2010 so I couldn't say if it was a thing back then.

There isn't a value that will throw an error with the exception of the compiler generated values and in certain cases. Sometimes you'll get a runtime error saying that a variable is being used before being initialized, but this isn't something you should count on. There are a few things you can do to avoid using uninitialized variables.

  1. Initialize all your variables, regardless the situation. If you can't init the value to what you need right away because you need to use an if statement or a for loop to get the value needed, initialize the variable to something you know isn't a valid value...something like -1 when you only need positive numbers, or nullptr for pointers.
  2. Use asserts before the usage of the variables. I should take my own advice on this one, I don't use asserts as often as I should, but it has saved me so much time debugging when a pixel leaves the screen in Chili's framework having those asserts in Graphics::PutPixel.
  3. Declare as many of your variables as const as possible. If the values aren't going to change through out the function call, then just declare them const. What this will do is force you to initialize the variables when declaring them, since you can't change them later, and if you try then you will get a compile time error. Even if you decide later you need to change them, at least you are aware that they are initialized and are going to be used right then.
  4. Don't declare all your variables at the top of the function, instead initialize your variables right before you use them. This way they are fresh on your mind and you shouldn't forget.
Anyway, hopefully that helps.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

User avatar
Zedtho
Posts: 189
Joined: February 14th, 2017, 7:32 pm

Re: Initialization and Constructors

Post by Zedtho » March 8th, 2017, 3:37 pm

Thanks a lot for the interesting info! This answered the last remaining questions for me :D

Post Reply