Jump to content
  • Advertisement
Sign in to follow this  
Bromordra

Pointers. Why?

This topic is 3235 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

Okay, I've been working through a C++ book for a while now and things have been going swimmingly, with me picking up each concept with great ease and retention. Then I got to pointers.I just don't get it. I can understand the syntax and the whole address-not-a-value thing about them, but I just can't retain them because I cannot see any practical application of them. Where and when would you use pointers in game development? I suppose that this may be my books fault because it teaches pointers by making you rewrite a program you already wrote using arrays by using vectors and iterators and stuff instead, and it all seems pointless (no pun intended) to me. Could you give some kind of practical example of where pointers would be used in game development(or any development for that matter)? I'm sorry if I sound ignorant and dumb, but I'm having serious trouble with this concept and really need help making it click. EDIT: Fixed a typo in the title

Share this post


Link to post
Share on other sites
Advertisement
The simplest reason is, you only have ~2MB of stack memory. If you need to use more than 2MB of memory, you need to allocate it with malloc/new (from which you get a pointer to retain the location of that object).

Another reason: you need an object to survive between different scopes or function calls, so allocate with malloc/new and pass it around via pointer.

In C++ you can also use polymorphism by retaining pointers to base class objects in a common list. Like all your game objects in a single list.

Dynamic memory data structures: linked list, binary tree, etc

Suffice it to say, they are vital. Right now they probably seem useless, but keep up your learning and their importance will become clear. By necessity, you have to introduce pointers before you introduce anything that uses pointers [smile]

-me

Share this post


Link to post
Share on other sites
imagine you have a game where the player has to carry 30 rocks from one side of the room to another (crappy game i know hehe).

so, your game has the following objects

PlayerObject -> 1 of these
RockObject -> 30 of these

when the player is moving a rock, you have to know which rock the player is moving. How do you do this? You have a pointer that points to which rock is being manipulated.

This lets you do this...

//make sure the rock moves as the player moves
PlayerObject.RockBeingCarried->Position = PlayerObject.Position

and if you want the player to move a different rock, you just set PlayerObject.RockBeingCarried to point to the new rock you want the player to be carrying.

hope that helps! (:

Share this post


Link to post
Share on other sites
Pointers encapsulate memory addresses. They allow you to operate on raw memory blocks, and to pass handles to such blocks around. It's a low level construct that is more convenient to use than assembly in low-level code that requires raw memory access.

C was originally designed to build the UNIX operating system, and C++'s backwards-compatibility to C includes pointers.

Share this post


Link to post
Share on other sites
Pointers are a means of providing reference semantics (I mean "reference" in the general sense, because C++ also has a concept of 'references' that mean something specific to C++, but also provide reference semantics).

They allow you to refer to something without actually having that something. A typical real world example is that of a house. If I want to show you my house, I give you my address (which can be viewed as a reference to my house). I don't build you a new copy of my house... that would be foolish.

There are many advantages to referential semantics, both from a performance perspective and a logical one. A reference of some sort to an object is often much smaller than the object itself, so passing it around is usually faster (the object itself is not copied, just the reference to that object). Additionally, without referential semantics, you wouldn't be able to write generalized functions such as apply_damage(Actor* actor) (which applies some damage to any arbitrary actor).

Note that we could also write apply_damage(Actor& actor) to use C++ references instead of pointers, and this would probably actually be preferable since references cannot be null, legally.

They are also how C++ allows you to get a reference to objects allocated at runtime (on the heap, via new).

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidine
The simplest reason is, you only have ~2MB of stack memory. If you need to use more than 2MB of memory, you need to allocate it with malloc/new (from which you get a pointer to retain the location of that object).

Another reason: you need an object to survive between different scopes or function calls, so allocate with malloc/new and pass it around via pointer.

In C++ you can also use polymorphism by retaining pointers to base class objects in a common list. Like all your game objects in a single list.

Dynamic memory data structures: linked list, binary tree, etc

Suffice it to say, they are vital. Right now they probably seem useless, but keep up your learning and their importance will become clear. By necessity, you have to introduce pointers before you introduce anything that uses pointers [smile]

-me


malloc? new? stack memory? Jeez . . . I'm starting to think my book is explaining things out of order, I've never heard any of those terms before. . . cripes.

Share this post


Link to post
Share on other sites
Here's a simple example, albeit one that is more for educational purposes than actual real use;

Say you're making a platformer game, where the player can run and jump. Let's assume you have a game controller with a DPad and A and B buttons, and you game code has a classes for Joystick, Button and Player to control them, something like this:


class Joystick {
public:
Button B;
Button A;
};

class player {
public:
Joystick joystick;
};

Joystick Joystick1;
Player Player1;






Imagine that these class do everything you'd expect them to do, there's obviously a bunch of code required, but this just imagine it all works for the sake of this example.

You might have some code like this:


void CheckForPlayerJump() {
if( Player1.joystick.B.isPressed() ) {
Player1.Jump();
}
}






This says, if player 1's joystick tells me they pressed the b button, make the player jump.

Simple right? Well what if the player changes the settings so that you the A button is the jump button? How would you do that? Here's how you could without pointers:


//Player uses the options screen to map the jump button to A which
//sets JumpButtonIsB to true
void CheckForPlayerJump() {
if( JumpButtonIsB ) {
if( Player1.joystick.B.isPressed() ) {
Player1.Jump();
}
} else {
if( Player1.joystick.A.isPressed() ) {
Player1.Jump();
}
}
}







Notice that we have the exact same code for A or B, with the exception of which button does the action. Now, here's how you might do that same thing with pointers:


Button *Player1Jump = &Joystick1.B;

void CheckForPlayerJump() {
if( Player1Jump->isPressed() ) {
Player1.Jump();
}
}






See how the jump-checking function doesn't have to know what button is used for jumping? All it knows is that some button is used, it doesn't care which one. Ever played a game where you could assign any key to any action? What if instead of a controller, you had a Keyboard class? Without pointers you might have something like this:


void CheckForPlayerJump() {
if( JumpButtonIsQ ) {
if( Keyboard.Q.isPressed() ) {
Player1.Jump();
}
} if( JumpButtonIsW ) {
if( Keyboard.W.isPressed() ) {
Player1.Jump();
}
} if( JumpButtonIsE ) {
if( Keyboard.E.isPressed() ) {
Player1.Jump();
}
}
...//'til we get all the letters
}






So you'd have to check every single key this way. Now you might say "Couldn't I just put all the keys in an array and have an int to tell me which to use?" You sure could, but what if the objects were not in an array? What if a variable is given to you from a function? What if you don't know exactly what button is pressed? here's how you might do that with pointers:


KeyboardKey *Player1Jump = &Keyboard.Q;//or whatever the user picks

void CheckForPlayerJump() {
if( Player1Jump->isPressed() ) {
Player1.Jump();
}
}







Simpler, no? Now imagine we have two Players who can set their button preferences however they like, which of these is better:

No pointer:

void CheckForPlayerJump() {
if( Player1_JumpButtonIsQ ) {
if( Keyboard.Q.isPressed() ) {
Player1.Jump();
}
} if( Player1_JumpButtonIsW ) {
if( Keyboard.W.isPressed() ) {
Player1.Jump();
}
} if( Player1_JumpButtonIsE ) {
if( Keyboard.E.isPressed() ) {
Player1.Jump();
}
}
...//'til we get all the letters for Player 1

if( Player2_JumpButtonIsQ ) {
if( Keyboard.Q.isPressed() ) {
Player2.Jump();
}
} if( Player2_JumpButtonIsW ) {
if( Keyboard.W.isPressed() ) {
Player2.Jump();
}
} if( Player2_JumpButtonIsE ) {
if( Keyboard.E.isPressed() ) {
Player2.Jump();
}
}
...//'til we get all the letters for Player 2
}






Or with pointers:

void CheckForPlayerJump( Player *p ) {
if( p.joystick.JumpButton->isPressed() ) {
p.Jump();
}
}

CheckForPlayerJump( Player1 );
CheckForPlayerJump( Player2 );






Much simpler. Also note, how the CheckForPlayerJump doesn't even know wick player it is using, it can work for any player.

One of the benefits of pointer is flexibility. You don't need to know exactly which object you are dealing with, you just need to know what type it is. When you are first starting out, that might not seem like a big deal, because all the programs in your book only have 2 or 3 objects. But when you are dealing with a game that has dozens, hundreds or thousands of objects, most of which are probably created on the fly, it's all but impossible not to use pointers.

Basically, one use of pointers in games is to deal with similar things in the same way, without having to hard code each one. Look up "Abstraction" on Google or Wikipedia to see why this is a good thing.

Another reason is that, when passing an object into a function, the entire object is copied to a local variable within that function. Passing a pointer to an object into a function just references the original object, without copying it. This means two things;
1) No needless copying, which can take a while depending on how bit the object is and,
2) You can modify the original object in the function


Your book had you use vectors and pointer instead of arrays, which isn't that big of a difference so you're right about that case being a bit unnecessary. But image if there was no array, that all those objects were created at run-time and just put into the vector.

[Edited by - NinjaMonkeyPirate on December 7, 2009 5:42:41 PM]

Share this post


Link to post
Share on other sites
You've covered references by now, surely? (Meaning specifically C++ ones with the "&")

At your stage, think of a pointer as being very similar to a reference as its used in similar circumstances. A few key differences are, with a pointer you can:

1) Increment it to point to the next type along in an array
2) Pass NULL to function expecting a pointer to indicate some optional behaviour that the function can pick up on given the NULL. Maybe the function would use the block of memory passed by a pointer, or if it's NULL then it would allocate a new block of its own or summat.

Both of these things can lead to bugs very easily, so use with care. Pointers do stuff that references can't, but the price is danger. (For example, maybe you shouldn't be allowed to increment it as in example 1), but theres nowt to stop you).

There are other uses, but those two should be enough for now. As others have said, you'll see why these things are as vital as int variables when you get a bit more general understanding.

Share this post


Link to post
Share on other sites
Quote:
Original post by NinjaMonkeyPirate
Here's a simple example, albeit one that is more for educational purposes than actual real use;

***truncated***



Wow . . . that. . . actually helped alot. Thank you. I think I really get it now.

And to Rubicon, no I haven't done references yet. The book I'm using seems to jump around alot, introducing things without explaining them and waiting until later parts of the book to explain what the heck was going on. Hence my frustration and confusion.

But yeah, thanks NMP, that seriously cleared this up for me.

EDIT: realized quoting the whole post was ugly, so I removed most of it.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!