2010-01-27 16 views
8

Soy un estudiante de programación con dos clases en C#, pero estoy tomando mi primera clase en C++, y por lo tanto estoy expuesto a punteros.¿Usos comunes para los indicadores?

Sé cómo funcionan, y la forma correcta de usarlos, pero me pregunté sobre algunas de las formas en que los programadores profesionales usan punteros en sus programas.

Entonces, ¿cómo se utilizan los punteros? ¿O usted?

Esto me ayudará a comprender algunas aplicaciones prácticas para los punteros, ¡así que gracias!

+0

Mire este para ver por qué los punteros a veces se utilizan para los parámetros: http://stackoverflow.com/questions/2139224/2139254#2139254 – sbi

Respuesta

16

En cualquier momento utilizaría una referencia en C#. Una "referencia" es solo un puntero con elegantes bolsas de aire de seguridad a su alrededor.

Uso los punteros una vez cada seis líneas en el código de C++ que escribo. En la parte superior de mi cabeza, estos son los usos más comunes:

  • Cuando necesito crear dinámicamente un objeto cuya vida excede el ámbito en el que fue creado.
  • Cuando necesito asignar un objeto cuyo tamaño es desconocido en tiempo de compilación.
  • Cuando necesito transferir la propiedad de un objeto de una cosa a otra sin copiarlo (como en una lista vinculada/montón/lo que sea de estructuras realmente grandes y caras)
  • Cuando necesito referirme al mismo objeto de dos lugares diferentes.
  • Cuando necesito cortar una matriz sin copiarla.
  • Cuando necesito escribir directamente en una región específica de la memoria (porque tiene asignada IO de memoria).
+1

"Cuando necesito referirme al mismo objeto desde dos lugares diferentes". Para eso, una referencia es a menudo mejor. – sbi

+0

No puede volver a colocar una referencia. Me refería a casos en los que tengo objetos A, B, X e Y, todos en diferentes ámbitos. X e Y deben referirse a A. Más adelante, sin crear una nueva X e Y, debo hacer que ambas se refieran a B. Si X e Y contienen un 'Foo & A', entonces no puedo volver a colocarlo en B. Podría tener algún tipo de clase de manejo elegante que tenga una función .Reseat(), pero internamente usaría un puntero de todos modos. – Crashworks

+0

"No puede volver a colocar una referencia". Por supuesto que no puedes. Pero eso no es necesario cada vez que necesita referirse al mismo objeto desde dos lugares diferentes. (Consulte los parámetros de la función, por ejemplo.) – sbi

1

Si tiene algo de tiempo en sus manos para leer un libro, le recomendaría leer The C Programming Language que hace un uso intensivo de los indicadores.

Un ejemplo sencillo de una función estándar:

/* strlen: return length of string s */ 
int strlen(char *s) { 
    char *p = s; 
    while (*p != '\0') p++; 
    return p - s; 
} 
+2

¿Y por qué alguien usaría eso en el código ** C++ ** real (excepto cuando escribiendo una clase de cuerda)? –

+0

Podrían necesitar calcular la longitud de una cadena. – Crashworks

+5

Permítanme reformular eso: no recomiende * El lenguaje de programación C * y el estilo C para alguien que comienza un curso de C++. –

6

Para estáteras, que ellos utilizan en su data structures, como lista enlazada, etc. en cualquier lugar que necesita asigna dinámicamente la memoria, es decir, la memoria que usted don' t saber el tamaño de en tiempo de compilación, utilizará un pointer.

1

Parte 1 de 2

punteros se requiere a menudo para interconectar con bibliotecas de C cuando los datos necesita ser pasado a una API existente. Este mecanismo no se limita a los sistemas "heredados", los ejemplos modernos incluyen OpenGL, DirectX y Win32.

a continuación es un ejemplo de OpenGL: glVertexPointer (int, float, int, float *) toma un puntero flotante como primer argumento.

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); 

en lugar de utilizar una matriz definida estáticamente que estaría bien para hacer lo siguiente:

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

o si desea utilizar std :: vector

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

Parte 2 de 2

Los punteros a objetos y punteros a función son útiles para definir la función de miembro estático que necesita operar en una instancia específica de una clase. Este idioma aparece en los mecanismos de devolución de llamada.

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(); 
} 

Si tiene control de callbackAPI se pueden lograr resultados similares con herencia y plantillas. Los ejemplos anteriores demuestran una forma de trabajar con un callbackAPI proporcionado por una tercera parte cuando se requiere para proporcionar un puntero a la función.

Cuestiones relacionadas