سؤال

I am learning C++ from a game development standpoint coming from long time development in C# not related to gaming, but am having a fairly difficult time grasping the concept/use of pointers and de-referencing. I have read the two chapters in my current classes textbook literally 3 times and even googled some different pages relating to them, but it doesn't seem to be coming together all that well.

I think I get this part:

#include <iostream>

int main()
{
    int myValue   = 5;
    int* myPointer = nullptr;

    std::cout << "My value: " << myValue << std::endl; // Returns value of 5.
    std::cout << "My Pointer: " << &myValue << std::endl; // Returns some hex address.

    myPointer  = &myValue; // This would set it to the address of memory.
    *myPointer = 10; // Essentially sets myValue to 10.

    std::cout << "My value: " << myValue << std::endl; // Returns value of 10.
    std::cout << "My Pointer: " << &myValue << std::endl; // Returns same hex address.
}

I think what I'm not getting is, why? Why not just say myValue = 5, then myValue = 10? What is the purpose in going through the added layer for another variable or pointer? Any helpful input, real life uses or links to some reading that would help make sense of this would be GREATLY appreciated!

هل كانت مفيدة؟

المحلول

The purpose of pointers is something you will not fully realize until you actually need them for the first time. The example you provide is a situation where pointers are not needed, but can be used. It is really just to show how they work. A pointer is a way to remember where memory is without having to copy around everything it points to. Read this tutorial because it may give you a different view than the class book does:

http://www.cplusplus.com/doc/tutorial/pointers/

Example: If you have an array of game entities defined like this:

std::vector<Entity*> entities;

And you have a Camera class that can "track" a particular Entity:

class Camera
{
private:
   Entity *mTarget;  //Entity to track

public:
   void setTarget(Entity *target) { mTarget = target; }
}

In this case, the only way for a Camera to refer to an Entity is by the use of pointers.

entities.push_back(new Entity());
Camera camera;
camera.setTarget(entities.front());

Now whenever the position of the Entity changes in your game world, the Camera will automatically have access to the latest position when it renders to the screen. If you had instead not used a pointer to the Entity and passed a copy, you would have an outdated position to render the Camera.

نصائح أخرى

TL;DR: pointers are useful when multiple places need access to the same information

In your example they aren't doing much, like you said it's just showing how they can be used. One thing pointers are used for is to connect nodes like in a tree. If you have a node structure like so...

struct myNode
{
    myNode *next;
    int someData;
};

You can create several nodes and link each one to the previous myNode's next member. You can do this without pointers, but the neat thing with pointers is because they are all linked together, when you pass around the myNode list you only need to pass the first (root) node.

The cool thing about pointers is that if two pointers are referencing the same memory address, any changes to the memory address are recognized by everything referencing that memory address. So if you did:

int a = 5; // set a to 5
int *b = &a; // tell b to point to a
int *c = b; // tell c to point to b (which points to a)

*b = 3; // set the value at 'a' to 3
cout << c << endl; // this would print '3' because c points to the same place as b

This has some practical uses. Consider you have a list of nodes linked together. The data in each node defines some sort of task that needs to be done that will be handled by some function. As new tasks are added to the list, they get appended to the end. Since the function has a pointer to the node list, as tasks are added on it receives those as well. On the other hand, the function can also remove tasks as it completes them, which are then reflected back across any other pointers that are looking at the node list.

Pointers are also used for dynamic memory. Say you want the user to enter in a series of numbers, and they tell you how many numbers they want to use. You could define an array of 100 elements to allow for up to 100 numbers, or you could use dynamic memory.

int count = 0;

cout << "How many numbers do you want?\n> ";
cin >> count;

// Create a dynamic array with size 'count'
int *myArray = new int[count];

for(int i = 0; i < count; i++)
{
    // Ask for numbers here
}

// Make sure to delete it afterwars
delete[] myArray;

If you pass an int by value, you will not be able to change the callers value. But if you pass a pointer to the int, you can change it. This is how C changed parameters. C++ can pass values by reference so this is less useful.

f(int i)
{
  i= 10;
  std::cout << "f value: " << i << std::endl;
}
f2(int *pi)
{
    *pi = 10;
    std::cout << "f2 value: " << pi << std::endl;
}

main()
{
    i = 5
    f(i)
    std::cout << "main f value: " << i << std::endl;
    f2(&i)
    std::cout << "main f2 value: " << i << std::endl;
}

in main the first print should still be 5. The second one should be 10.

What is the purpose in going through the added layer for another variable or pointer?

There isn't one. It's a deliberately contrived example to show you how the mechanism works.

In reality, objects are often stored, or accessed from distant parts of your codebase, or allocated dynamically, or otherwise cannot be scope-bound. In any of these scenarios you may find yourself in need of indirectly referring to objects, and this is achieved using pointers and/or references (depending on your need).

For example some objects have no name. It can be an allocated memory or an address returned from a function or it can be an iterator. In your simple example of course there is no need to declare the pointer. However in many cases as for example when you deal with C string functions you need to use pointers. A simple example

char s[] = "It is pointer?";

if ( char *p = std::strchr( s, '?' ) ) *p = '!';  

We use pointers mainly when we need to allocate memory dynamically. For example,To implement some data structures like Linked lists,Trees etc.

From C# point of view pointer is quite same as Object reference in C# - it is just an address in memory there actual data is stored, and by dereferencing it you can manipulate with this data.

First of non-pointer data like int in your example is allocated on the stack. This means that then it goes out of the scope it's used memory will be set free. On the other hand data allocated with operator new will be placed in heap (just like then you create any Object in C#) resulting that this data will not be set free that you loose it's pointer. So using data in heap memory makes you do one of the following:

  • use garbage collector to remove data later (as done in C#)
  • manually free memory then you don't need it anymore (in C++ way with operator delete).

Why is it needed? There are basically three use-cases:

  1. stack memory is fast but limited, so if you need to store big amount of data you have to use heap
  2. copying big data around is expensive. Then you pass simple value between functions on the stack it does copying. Then you pass pointer the only thing copied is just it's address (just like in C#).
  3. some objects in C++ might be non-copyable, like threads for example, due to their nature.

Take the example where you have a pointer to a class.

struct A
{
    int thing;
    double other;
    A() {
        thing = 4;
        other = 7.2;
    }
};

Let's say we have a method which takes an 'A':

void otherMethod()
{
    int num = 12;
    A mine;
    doMethod(num, mine);
    std::cout << "doobie " << mine.thing;
}

void doMethod(int num, A foo)
{
    for(int i = 0; i < num; ++i)
        std::cout << "blargh " << foo.other;
    foo.thing--;
}

When the doMethod is called, the A object is passed by value. This means a NEW A object is created (as a copy). The foo.thing-- line won't modify the mine object at all as they're two separate objects.

What you need to do is to pass in a pointer to the original object. When you pass in a pointer, then the foo.thing-- will modify the original object instead of creating a copy of the old object into a new one.

Pointers (or references) are vital for the use of dynamic polymorphism in C++. They are how you use a class hierarchy.

Shape * myShape = new Circle();
myShape->Draw(); // this draws a circle
// in fact there is likely no implementation for Shape::Draw

Attempts to use a derived class through a value (instead of pointer or reference) to a base class will often result in slicing and losing the derived data portion of the object.

It makes a lot more sense when you're passing the pointer to a function, see this example:

void setNumber(int *number, int value) {
    *number = value;
}

int aNumber = 5;
setNumber(&aNumber, 10);
// aNumber is now 10

What we're doing here is setting the value of *number, this would not be possible without the use of pointers.

If you defined it like this instead:

void setNumber(int number, int value) {
    number = value;
}

int aNumber = 5;
setNumber(aNumber, 10);
// aNumber is still 5 since you're only copying its value

It also gives better performance and you're not wasting as much memory when you're passing a reference to a larger object (such as a class) to a function, instead of passing the whole object.

Well to use pointers in programming is a pretty concept. And for dynamically allocating the memory it is essentiall to use pointers to store the adress of the first location of the memory which we have reserved and same is the case for releasing the memory, we need pointers. It's true as some one said in above answer that u cannot understand the use of poinetrs until u need it. One example is that u can make a variable size array using pointers and dynamic memoru allocation. And one thing important is that using pointers we can change the actual value of the location becaues we are accessing the location indirectly. More ever, when we need to pass our value by refernce there are times when references do not work so we need pointers.

And the code u have written is using dereference operator. As i have said that we access the loaction of memory indirectly by using pointers so it changes the actuall value of the location like reference objects that is why it is printing 10.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top