views:

234

answers:

4

Hi,

I'm a programming student with two classes in C#, but I'm just taking my first class in C++, and thus I'm being exposed to pointers.

I know how they work, and the proper way to use them, but I wondered about some of the ways that professional programmers use pointers in their programs.

So how do you use pointers? Or do you?

This will help me understand some practical applications for pointers, so thanks!

A: 

If you have some time on your hands for reading a book, I would recommend reading The C Programming Language which makes heavy use of pointers.

A simple example of a standard function:

/* strlen: return length of string s */
int strlen(char *s) {
    char *p = s;
    while (*p != '\0') p++;
    return p - s;
}
cobbal
And why would anyone use that in actual **C++** code (except when writing a string class)?
Georg Fritzsche
They might need to compute the length of a string.
Crashworks
Let me rephrase that: please don't recommend *The C Programming Language* and C-style for someone who starts a C++ course.
Georg Fritzsche
Good point. I do recommend it if you really want to understand how to use pointers though
cobbal
+5  A: 

For staters, you use them in your data structures, like linked list, etc. Anyplace you need dynamically allocated memory, that is, memory that you don't know the size of at compile-time, you will be using a pointer.

Muad'Dib
+11  A: 

Any time you'd use a reference in C#. A "reference" is just a pointer with fancy safety airbags around it.

I use pointers about once every six lines in the C++ code that I write. Off the top of my head, these are the most common uses:

  • When I need to dynamically create an object whose lifetime exceeds the scope in which it was created.
  • When I need to allocate an object whose size is unknown at compile time.
  • When I need to transfer ownership of an object from one thing to another without actually copying it (like in a linked list/heap/whatever of really big, expensive structs)
  • When I need to refer to the same object from two different places.
  • When I need to slice an array without copying it.
  • When I need to write directly to a specific region of memory (because it has memory-mapped IO).
Crashworks
"When I need to refer to the same object from two different places." For that one, a reference is often better.
sbi
Crashworks
"You can't reseat a reference." Of course you can't. But that's not needed every time you need to refer to the same object from two different places. (See function parameters, for example.)
sbi
A: 

Part 1 of 2

Pointers are often required to interface with C libraries when data needs to be passed into an existing API. This mechanism is not limited to "legacy" systems, modern examples include OpenGL, DirectX, and Win32.

below is an example from OpenGL: glVertexPointer(int,float,int,float*) takes a float pointer as the first argument.

GLfloat vertices[] = {...}; // 24 of vertex coords
...
// activate and specify pointer to vertex array
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);

// draw a cube
glDrawArrays(GL_QUADS, 0, 24);

// deactivate vertex arrays after drawing
glDisableClientState(GL_VERTEX_ARRAY);

instead of using an statically defined array it would be ok to do the following:

Glfloat *vertex = new GlFloat[24];
...
glVertexPointer(3, GL_FLOAT, 0, vertices);
...
delete [] vertex.

or if you want to use std::vector

std::vector<Glfloat> vertex;
vertex.resize(24);
...
glVertexPointer(3, GL_FLOAT, 0, &vertices[0]);
...

Part 2 of 2

Pointers to objects and function pointers are useful in defining static member function that needs to operate on a specific instance of a class. This idiom appears in callback mechanisms.

class foo {
  ...
  public:
    static int s_callback0(void* obj){
      return (foo*)(obj)->callback0();
    } 
    int callback0(){
      ...
    }
    ...
};

class callbackAPI {
  public:
    int setCallback(int(*fn)(void*),void* context){
      m_fn(fn);
      m_context(context);
    }
    void run (){
      m_fn(m_context);
    }
  private:
    int(*m_fn)(void*);
    void *m_context;
};

main {
  foo f;
  callbackAPI cb;
  cb.setCallback(foo::s_callback0,f);
  cb.run();
}

If you have control of callbackAPI similar results could be achieved with inheritance and templates. The above examples demonstrates a way of working with a callbackAPI provided by a 3rd party when required to provide a function pointer.

Marc