Register    Login    Forum    Search    FAQ

Board index » Everything




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post Posted: March 12th, 2017, 10:03 pm 
User avatar

Joined: February 16th, 2017, 12:04 am
Posts: 6
Location: Spain
Thanks to the Beginner C++ tutorial, I understood that references are useful for passing objects to a function, but I have no idea in which situations pointers are necessary. If I'm not wrong, the main purpose of pointers is to dynamically allocate memory, that's the reason why vector class uses them a lot. However, apart from that example, I don't know how I can take advantage of pointers in my projects. Can anyone give me an example?


Top 
 Profile  
Reply with quote  
 Post Posted: March 13th, 2017, 1:18 am 
Site Admin
User avatar

Joined: December 31st, 2011, 4:53 pm
Posts: 3176
Location: Japan
Yeh, the main advantage of pointers over references is they are retargettable. This makes them very well-suited as a handle on heap-allocated memory, mainly because we can set pointers to 0 to indicate that they are 'empty', whereas references aren't ever supposed to be used except for memory that is 100% guaranteed 'to be there'.

The other thing is, because they can be retargetted, they're great for managing connections between entities that can be changed during the life of an object. Also, when you have an object that has assignment operators defined, references aren't gonna work (because they can't be re-seated), and so you gotta use pointers. And if you wanna use an object directly in a container, you need for it to be copy or move-assignable (the alternative is to wrap it in std::reference_wrapper or to push it into the container as an std::unique_ptr).

Finally, a lot of APIs / libs use pointers extensively, even when a ref& would suffice, so you just gotta roll with the punches in that case (Box2D comes to mind as a prime example).

_________________
Chili


Top 
 Profile  
Reply with quote  
 Post Posted: March 13th, 2017, 10:33 am 
User avatar

Joined: February 16th, 2017, 12:04 am
Posts: 6
Location: Spain
Chili wrote:
Also, when you have an object that has assignment operators defined, references aren't gonna work (because they can't be re-seated), and so you gotta use pointers.


I don't actually understand that point. Looking at your Vec2 class, is this a good example to illustrate that?

Code:
Vec2 Vec2::GetNormalized() const
{
   const double len = GetLength();
   if( len != 0.0f )
   {
      return *this * (1.0f / len);
   }
   return *this;
}


Or this:

Code:
Vec2& Vec2::operator+=( const Vec2& rhs )
{
   return *this = *this + rhs;
}


Chili wrote:
Finally, a lot of APIs / libs use pointers extensively, even when a ref& would suffice


So for example, are these two options the same or is one better than the other?

Option 1:
Code:
void addFive(int* a)
{
  *a += 5;
}

int main()
{
  int a = 5;
  addFive(&a);
  return 0;
}


Option 2:
Code:
void addFive(int& a)
{
  a += 5;
}

int main()
{
  int a = 5;
  addFive(a);
  return 0;
}


Top 
 Profile  
Reply with quote  
 Post Posted: March 13th, 2017, 1:11 pm 
 

Joined: February 28th, 2013, 3:23 am
Posts: 2436
Location: Oklahoma, United States
The assignment issue is like this

int a = 5;
int &b = a;
int c = 7;
b = c; // b is assigned to a so a and b are now 7, this doesn't reassign b to c

If you had a class that held a reference, then tried to assign one copy of the class to another, it would fail because you can't reassign the reference, only the values the reference refers to.

Pointers in C++ as a general rule of thumb should really only be used for arrays or basically a block of memory. Objects should be referenced using a reference. Pass const references or references to functions instead of pointers, makes coding look better and more readable with less error prone code. Don't return references unless as chili says, it's guaranteed to be a legit reference to an object. Only return pointers from functions when you need to check if the returned value is valid as in
Code:
MyClass *pObject = GetObjectAddress();
if( pObject != nullptr )
     // do whatever
else
     // handle case of nullptr


The way I look at it is, if I'm dealing with memory I use pointers, if I'm dealing with class objects, I use references. Parameters are always ref or const ref. Return from functions depends on a few things. If it's a class member, then by const ref. If it's an object that is conditional ( may or may not exist ), then by pointer. All else, I return by value.

To clarify, what I mean by conditional is this. Say you have a grid of tiles and you create a function to return a tile to you from that grid based on some condition. If the condition is false, what do you return? You can't return nothing, so your only options are return a pointer as a nullptr or return a newly created object which doesn't always work out well...I've tried. In this case, I end up creating a second function to test for the condition and it returns a bool, and if true then I get that tile and if false, I skipped whatever needed to be done.

_________________
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


Top 
 Profile  
Reply with quote  
 Post Posted: March 14th, 2017, 2:15 pm 
Site Admin
User avatar

Joined: December 31st, 2011, 4:53 pm
Posts: 3176
Location: Japan
Saturos wrote:
Chili wrote:
Also, when you have an object that has assignment operators defined, references aren't gonna work (because they can't be re-seated), and so you gotta use pointers.


I don't actually understand that point. Looking at your Vec2 class, is this a good example to illustrate that?

Code:
Vec2 Vec2::GetNormalized() const
{
   const double len = GetLength();
   if( len != 0.0f )
   {
      return *this * (1.0f / len);
   }
   return *this;
}


Or this:

Code:
Vec2& Vec2::operator+=( const Vec2& rhs )
{
   return *this = *this + rhs;
}



Nah, what I'm talking about is like when the class has a member variable that is a pointer. You will see when we get that far in the tutorials. It's hard to demonstrate without a good concrete and somewhat detailed example. I guess you could say, like if you had a tank, and it could have different main cannons attached. The Cannon* pCannon; member would be like a socked that you could attach different Cannon objects to over the course of the life of the tank. Something like that.

_________________
Chili


Top 
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
 
Post new topic Reply to topic  [ 5 posts ] 

Board index » Everything


 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
cron