# When To Use Pointers?

## Recommended Posts

I've just moved from C#/Java to C++ and, as you might expect, a big problem I'm facing is understanding when to use pointers (I know that Java and C# use pointers under the hood but I never needed to understand them to program :P). I understand conceptually what pointers are but I can't seem to think of when to actually use them over just plain objects, except for perhaps arrays.

What makes it worse is that while most people on the internet say to avoid pointers when possible, whenever I read source codes for game engines and for games developed in C++, I see pointers everywhere.

For example, an excerpt from Game Programming Patterns:

class GameObject
{
public:
int velocity;
int x, y;

GameObject(InputComponent* input,
PhysicsComponent* physics,
GraphicsComponent* graphics)
: input_(input),
physics_(physics),
graphics_(graphics)
{}

void update(World& world, Graphics& graphics)
{
input_->update(*this);
physics_->update(*this, world);
graphics_->update(*this, graphics);
}

private:
InputComponent* input_;
PhysicsComponent* physics_;
GraphicsComponent* graphics_;
};

Why shouldn't InputComponent, PhysicsComponent, and GraphicsComponent just be objects?

I guess all I'm asking for is help understanding why and when to use pointers.

Thanks (sorry for all the text).

##### Share on other sites

If you passed in Objects rather than pointers to objects, they would be copies. So if you modify them or get data from them, you would be modifying the copies. The original ones (perhaps a core part of you engine) will remain unchanged. This is obviously an issue if you added (i.e) a new Physics object to the *copy* of the PhysicsComponent, the original PhysicsComponent will remain unchanged causing issues later when you query the original expecting the additional Physics object to be registered.

In C#, I see a lot of inexperienced developers make the same mistake for "boxed" value types like structs. They modify a Vector3 for example, pass that Vector3 into some other class but then modify the original Vector3 again, expecting it to change the Vector3 in the other class. In C# *everything* acts a pointer apart from structs/boxed types.

// C# using a library where Vector3 is a struct, value type
Vector3 v = new Vector3();
player.position = v;
v.x = 99;
// player.position.x is not 99

// C++ (avoiding pointers)
Vector3 v;
player->position = v;
v.x = 99;
// player->position.x is not 99

// C# using a library where Vector3 is a class
Vector3 v = new Vector3();
player.position = v;
v.x = 99;
// player.position.x is 99

// C++ (using pointers)
Vector3 *v = new Vector3();
player->position = v;
v->x = 99;
// player->position->x is 99

Perhaps refer to the following complexity in C# to better understand how C++ handles this situation: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/boxing-and-unboxing

When people say do not use pointers in C++... that simply isn't feasible. Perhaps they mean they use smart pointers with references as parameters instead? Either way, unless they only stick to OpenGL's GLuint type system, I cannot see them avoiding pointers when dealing with 3rd party C libraries such as SDL. Would be cool to be proved otherwise. Can anyone point me towards a largish project where this is the case?

Edited by kop0113

##### Share on other sites

You use pointers when you want referential semantics. That is, you want to be able to refer to some object without actually needing a complete copy.

I can't speak 100% to the rationale for why pointers are used in that code example you provided, as I didn't write it. I can theorize, however. One reason to use pointers here would be if the components are owned by something else, and the game object just needs to be able to refer to the components it owns.

For example, a typical way to implement a game object system using an "entity and component" approach like this is to have all the actual instances of the PositionComponent objects stored in, say, a PhysicsSystem. This system is responsible for the actual lifetime (creating and destroying) the position components, as well as updating them all in one big cache-friendly batch during the game update.

Individual game objects get pointers to the position component that represents their position, so they can read from it when needed. Pointers enable this design; if the game object just has its own copy of a position component, that copy is distinct from any copies in the position system.

You can implement a game object that stores its position component (et cetera) directly if you want. You don't have to use pointers there. But in the particular example you provided, the pointers are being used to refer to an object that is managed elsewhere, which is in general a common use case for referential semantics.

##### Share on other sites

simply put, a pointer should be used as a memory saving practice. sometimes there are objects that a very large and use a lot of memory. for example in the code above, PhysicComponent could be referring to an entire library of 1000s of lines of code. and a single instance of the Physic Component could be several MBytes. then consider that when you pass the object into another function, that function creates a COPY of that object. therefore with each call to that instance, there could be multiple copies of it at runtime. In come pointers. with a pointer we pass only the address of the Obj to the function instead of its value. now there is only one copy of that instance needed for our code to work at runtime

consider the following:

using namespace std;
#include<hugeLibrary.h>
int main()
{
Library test[100];//an array of objs
for(int x = 0;x<100;x++){

Lbrary lib = hugeLibrary();//2Mb of data
test[x] = lib;
}
//test now is 200Mb
startEngine(test);
doSomething(test);
closeEngine(test);//each call results in a Copy of test being created

}

or-

int main(){
Library* test[100];//an array of pointers
for(int x = 0;x<100;x++){

Lbrary lib* = &(hugeLibrary());//32bits of data
test[x] = lib;
}
//test now is 3kb
startEngine(test);
doSomething(test);
closeEngine(test);//each call results in a Copy of test being created

}

PS. this is an Extremely simplified answer. technically each lib would be also be destroyed after each function lost scope.

Edited by dcoolllx

##### Share on other sites

Ohh, that makes a lot more sense, thanks! On a side note, I was wondering on whether it's better to use smart pointers vs raw pointers when developing games. I know lots of people recommend using smart pointers to avoid the hassle of raw pointers, but when it comes to developing games, would having the additional control over when to free the pointers be worth the trouble?

##### Share on other sites
13 minutes ago, dertharino said:

but when it comes to developing games, would having the additional control over when to free the pointers be worth the trouble?

No.

##### Share on other sites
27 minutes ago, dertharino said:

I know lots of people recommend using smart pointers to avoid the hassle of raw pointers, but when it comes to developing games, would having the additional control over when to free the pointers be worth the trouble?

It's important for you to understand how regular, "non-smart" pointers work, so I do encourage you to learn. But once you learn how, it should illustrate just how much more useful smart pointers are when it comes to the actual management of object lifetimes. There are very few cases where "having additional control over when to free the pointers" is worth the trouble, and none of them are applicable to a beginner.

That said, smart pointers are not a magical bullet and I disagree with the common dogma that says a regular pointer should never appear in one's code. Generally I use smart pointers such as std::unique_ptr (I rarely have a concrete need for std::shared_ptr) where I need to use a pointer to manage lifetime. I use a bare pointer where I need a nullable reference and lifetime management isn't involved.

Another way to say that is that systems that own objects might keep smart pointers referring to those objects, but hand out bare pointers to client code if handing out a C++ reference ("Thing&") isn't feasible.

If this seems like too subtle a distinction, then I encourage you to simply use smart pointers until you are more comfortable with the ins and outs of lifetime management in code architecture, and then revisit the topic with your improved understanding and experience at a later time.

##### Share on other sites
1 minute ago, jpetrie said:

That said, smart pointers are not a magical bullet and I disagree with the common dogma that says a regular pointer should never appear in one's code. Generally I use smart pointers such as std::unique_ptr (I rarely have a concrete need for std::shared_ptr) where I need to use a pointer to manage lifetime. I use a bare pointer where I need a nullable reference and lifetime management isn't involved.

I was going to post basically the exact same thing and agree completely.

I also use raw pointers in places where the lifetime management is know and handled by something else.  You'll quite commonly find raw pointers in class internals as private members since you know when they are created, when they are accessed, when they are destroyed, and who owns what.  When in doubt use a smart pointer.  Many others will suggest to always use smart pointers, which isn't a terrible thing, but is more a 'rule of thumb' for beginners than a hard and fast rule.

##### Share on other sites
23 minutes ago, jpetrie said:

That said, smart pointers are not a magical bullet and I disagree with the common dogma that says a regular pointer should never appear in one's code. Generally I use smart pointers such as std::unique_ptr (I rarely have a concrete need for std::shared_ptr) where I need to use a pointer to manage lifetime. I use a bare pointer where I need a nullable reference and lifetime management isn't involved.

Another way to say that is that systems that own objects might keep smart pointers referring to those objects, but hand out bare pointers to client code if handing out a C++ reference ("Thing&") isn't feasible.

That makes a lot of sense too. Thanks again!

32 minutes ago, felipefsdev said:

I saw this image days ago, I liked how didactic it is:

Haha this is a really good graphic. Thanks for that!

##### Share on other sites

The default case is to work by value:

void doThing(int num) { num++; }

In this case 'num' is a copy of whatever you pass in when calling the function.

int derp = 1;
doThing(derp);
//derp still equals 1 because it was a copy that got incremented

If you want to be able to modify the original value then you can pass by reference:

void doThingByRef(int& num) { num++; }

Now 'num' is effectively a direct alias of whatever you pass in:

int derp = 1;
doThing(derp);
//derp now equals 2

There's another case to consider... What if the thing you're passing in is large, but you don't want to modify it?

You don't want to do an unnecessary copy, so you may use a reference, but that suggests that you're modifying the item within the function. In this case you could use a const reference:

void doThingByConstRef(const BigThing& thing) { ??? }

This lets you read 'thing' but not modify it (you'll get a compile error).

These are the basics of reference semantics. Pointers are similar, but they have some additional properties:

1) A pointer is "nullable". That is, it can be set to 'nulllptr' in order to indicate that it doesn't actually point to anything.

2) A pointer is "reseatable". That is, it can be modified to point at something else.

A note about pointers and constness:

int* num; //the pointer can be changed and the int that it points to can be changed
const int* num; //the pointer can be changed but the int that it points to can not
int* const num; //the pointer can not be changed but the int that it points to can be (probably use a reference instead in this case)
const int* const num; //neither the pointer or the pointed-to int can be changed (probably just use a const reference instead)

Be careful about returning pointers and references from functions. If the thing that you're referring to is destroyed or moved then you end up with a dangling reference/pointer, and that's no fun at all.

So the basic rule of thumb here is:

Use value semantics by default.

Use references when you want references.

Use pointers when you want references that are reseatable and/or nullable.

Cheers.

Edited by Khatharr

##### Share on other sites

My experience of pointer use is perhaps slightly different to some others on this thread, as I work on a fork of Simutrans, which has a very old codebase (1990s), and which uses pointers in a more traditional way: basic pointers are usually used whenever reference semantics are needed (and references used fairly occasionally). "Quickstone" type smart pointers (a variant on the "tombstone" system, the code for the smart pointers being custom written for this specific game) are used in certain special cases where one part of the code cannot easily know whether a pointer to an object in another part of the code has been deleted. Typically, this is used for in-game objects (such as vehicles) which the player may delete at any time. Null pointers (using a preprocessor definition of NULL as 0x000000, as the codebase was written before nullptr was standard) are used frequently for logic operations (e.g., if a player queries a tile of ground that does not have a way such as a road on it, the function that returns a pointer to a way will return NULL, which then has to be checked in the logic for deciding what information to display before attempting to retrieve any data from that object).

This more traditional use of pointers is, I suspect, a little faster but considerably more error-prone than the more modern approach suggested here of using smart pointers in all cases. I do not necessarily recommend that approach in a new project, but it may be useful to know that this is how things were done in the past to put your understanding of the use of pointers into some perspective, and it may well also be useful if you were ever to work on an older codebase where these older techniques are still used.

## Create an account

Register a new account

• 10
• 12
• 10
• 10
• 11
• ### Similar Content

• Good Evening,
I want to make a 2D game which involves displaying some debug information. Especially for collision, enemy sights and so on ...
First of I was thinking about all those shapes which I need will need for debugging purposes: circles, rectangles, lines, polygons.
I am really stucked right now because of the fundamental question:
Where do I store my vertices positions for each line (object)? Currently I am not using a model matrix because I am using orthographic projection and set the final position within the VBO. That means that if I add a new line I would have to expand the "points" array and re-upload (recall glBufferData) it every time. The other method would be to use a model matrix and a fixed vbo for a line but it would be also messy to exactly create a line from (0,0) to (100,20) calculating the rotation and scale to make it fit.
If I proceed with option 1 "updating the array each frame" I was thinking of having 4 draw calls every frame for the lines vao, polygons vao and so on.
In addition to that I am planning to use some sort of ECS based architecture. So the other question would be:
Should I treat those debug objects as entities/components?
For me it would make sense to treat them as entities but that's creates a new issue with the previous array approach because it would have for example a transform and render component. A special render component for debug objects (no texture etc) ... For me the transform component is also just a matrix but how would I then define a line?
Treating them as components would'nt be a good idea in my eyes because then I would always need an entity. Well entity is just an id !? So maybe its a component?
Regards,
LifeArtist
• By nickyc95
Hi.
I'm kind of late to this party but I thought I would ask anyway as I haven't found a concrete answer.

When creating a game engine, when should you choose one methodology over another (more specifically OOP and DOD)? Which areas benefit from DOD? Which areas benefit from OOP? Do people typically mix multiple methodologies throughout a project? I.e. certain sub-systems created in one, and others in the another?
DOD - Data Oriented Design
OOP - Object Oriented Design

Pretty simple
Thanks
• By Estra
Memory Trees is a PC game and Life+Farming simulation game. Harvest Moon and Rune Factory , the game will be quite big. I believe that this will take a long time to finish
Looking for
Programmer
1 experience using Unity/C++
2 have a portfolio of Programmer
3 like RPG game ( Rune rune factory / zelda series / FF series )
4 Have responsibility + Time Management
and friendly easy working with others Programmer willing to use Skype for communication with team please E-mail me if you're interested
Split %: Revenue share. We can discuss. Fully Funded servers and contents
and friendly easy working with others willing to use Skype for communication with team please E-mail me if you're interested
we can talk more detail in Estherfanworld@gmail.com Don't comment here
Thank you so much for reading
Memory Trees : forget me not

Thank you so much for reading
Ps.Please make sure that you have unity skill and Have responsibility + Time Management,
because If not it will waste time not one but both of us

• By mike44
typedef struct FontInfo_t* FontHandle;
MichaelNS::FontMgr m;
const char *FontPtr;
start:
InFileFont.append("Ubuntu-B.ttf");
FontPtr = InFileFont.c_str();
stop:
delete FontPtr;
delete causes a crash. How to unload the class correctly?
Thanks

• I need to use global vars,
So say i have main.cpp file where i #include "globalvars.h"
In globalvars.h i define
extern int ppp;
In globalvars.cpp i put #include "globalvars.h"
int ppp;

Now in main cpp during compilation i get UNDEFINED REFERENCE TO ppp