¿Cuál es la diferencia entre un puntero y un mango?

No puedo decir que tengo una sólida formación en C++, por lo que escucho Handle muy a menudo en estos días. Sé qué es un puntero (que almacena la dirección de la ubicación de la memoria como referencia), pero no estoy seguro de qué es Handle y cuáles son las diferencias entre estos dos. Y un código de muestra en C# sería genial si pudiera proporcionar uno.

Por cierto, busqué en Google estos términos, sin embargo, muchas personas dieron diferentes explicaciones, así que creo que obtuve la mejor de SO.

EDIT:

Un aviso rápido para los otros visitantes: Un identificador es como una referencia que señala un recurso. Puede apuntar a una dirección de memoria como un puntero, pero Manejar es un término más general, por lo que es más como un pseudo-puntero. Un archivo es un buen ejemplo de esto. Un archivo puede tener una identificación que el sistema operativo puede entender y usar para encontrar el archivo. Entonces, Handle puede contener esta ID (que puede ser o no una dirección de memoria) y cuando pasamos este Handle, el sistema operativo puede encontrar el archivo fácilmente.

Consulte las respuestas a continuación para obtener información más detallada.

Edit:

Todas las respuestas bajo esta pregunta son increíbles y muy explicativas. Me está costando mucho seleccionar uno de ellos para marcarlo como respuesta.

preguntado el 22 de mayo de 12 a las 15:05

¿Estás hablando de identificadores c++/cli? stackoverflow.com/questions/1820841/… ? O simplemente el concepto de "un identificador" en c/c++: stackoverflow.com/questions/1303123/qué-es-un-mango-en-c -

Estoy preguntando sobre algo más general y si hay alguno, entonces C#. -

Echa un vistazo a esta respuesta de la mía, debería ayudar. -

3 Respuestas

Lo siento, no hay ejemplo de C#, pero:

El puntero es una dirección de memoria, que en este caso apunta a dónde se almacena el objeto en la memoria. Este es un concepto de bajo nivel que C++ heredó de C.

En cuanto al mango:

El término manejador se usa para referirse a cualquier técnica que le permita llegar a otro objeto: un pseudo-puntero generalizado. El término es (intencionalmente) ambiguo y vago.

Otro término importante que está estrechamente relacionado es una referencia de objeto, que es un "alias" para el objeto.

Puede obtener respuestas bastante claras y concisas sobre esta página

Respondido 23 Feb 15, 06:02

OK, esto es lo que entendí de tu explicación. A Pointer debe tener una dirección de memoria para ser llamado puntero. Handle es un término más general y no tiene que contener una dirección de memoria, sino cualquier valor entero que el kernel pueda entender. Entonces, un identificador puede almacenar un 1234545 que no es una dirección de memoria, pero el kernel usa ese número para identificar un archivo en una tabla, tal vez. Pero Handle también puede almacenar direcciones de memoria y puede usarse como Pointer también. ¿Está bien? - Tarik

Eso es correcto. Solo para que quede claro, un puntero is una dirección de memoria, mientras que handle es más bien una abstracción, que puede implementarse como un puntero, como usted dice: Alex Kreimer

Un identificador es un identificador de objetos abstractos (mapas de bits, sockets, archivos, memoria, etc.) que se utiliza para identificar qué objeto se ve afectado por una operación: HBITMAP, socket, FILE* son ejemplos de identificadores; de hecho, son números enteros que posiblemente representan un índice en alguna tabla o mapa en el sistema operativo.

Estrictamente hablando, un puntero es una ubicación precisa en la memoria. Si bien un puntero se usa a veces como un identificador, lo contrario rara vez (o nunca) es cierto.

En entornos orientados a objetos, los identificadores se consideran entidades de bajo nivel y es una buena práctica envolver identificadores en objetos con el objeto que tiene métodos que llaman a las operaciones utilizando el identificador asignado. En ese caso, tiene una referencia a un objeto que tiene un mango, por ejemplo: CBitmap, System.Net.Sockets.Socket, std::fstream, etc.

Sin ahondar en un idioma de guerra religiosa, algunos argumentarán que uno u otro es más limpio, más seguro, más rápido, más fácil. Casi siempre depende del entorno en el que se encuentre; no sería recomendable usar identificadores directamente en C# si tiene la opción, mientras que en C será mucho más simple (y necesario) usar identificadores.

Nota importante: En el entorno .Net, si alguna vez tiene que realizar un cálculo de referencias, terminará leyendo algo sobre las referencias de objetos reales que se denominan identificadores. Esto se debe a que, de hecho, son manijas debajo del capó en lugar de punteros. Entonces, cuando llama a un método en un objeto, el compilador en realidad está llamando al método con un identificador a un objeto que puede moverse libremente en la memoria. Esto hace posible que el recolector de basura evite la fragmentación de la memoria. Así que con un System.Drawing.Bitmap terminas con un identificador a un puntero a un identificador.

EDIT:

Ejemplo, stdio/fstream en C++:

// Read a short line from a file and output it to the console
// 256 bytes max for simplicity purposes

char buffer[256];

// With handle
FILE* file = fopen ("file.txt" , "r");
fgets(buffer, 256 , file);
std::cout << buffer << std::endl;
fclose (file);

// With object reference
{
  std::ifstream stream ("file.txt");
  stream.getline(buffer, 256);
  std::cout << buffer << std::endl;
}

El ejemplo superior usa lo que debería considerarse un identificador FILE* a un archivo. El file el identificador se asigna mediante fopen y pasó a operaciones como fgets() y close(). close() desasignar el mango.

El ejemplo inferior usa std::ifstream. El identificador se asigna en el constructor de objetos y es interno a ese objeto. Para realizar operaciones en el archivo, utiliza el método proporcionado por ese objeto, como getline(). El identificador es desasignado por el destructor de flujo cuando el objeto sale del alcance, es decir, en el paréntesis de cierre, o si el objeto se asignó en el montón, deberá eliminarlo explícitamente.

contestado el 22 de mayo de 12 a las 16:05

Me gusta mucho esta explicación. ¿Consideraría armar un pequeño código de muestra que puede estar en C ++ o en cualquier otro idioma que muestre un ejemplo del mundo real en el que necesito usar uno? - Tarik

Un identificador es solo una pieza de información que sirve como sustituto de un recurso.

El ejemplo más común es un identificador de archivo, que a menudo no es más que un número entero que se asigna a cada archivo que abre para que pueda distinguirlos. Se usan con mucha más frecuencia en lenguajes como C, donde todo el archivo. open() devuelve un número entero y, a continuación, en todas las demás funciones de acceso a archivos, debe pasar ese valor como argumento para especificar a qué archivo se refiere. Por ejemplo, en la función int read(int fd, void * ptr, int numbytes), lo pasarías como el argumento para fd.

C proporciona 3 identificadores de archivos estándar que deberían sonar familiares:

  • 0: entrada estándar
  • 1: salida estándar
  • 2: error estándar

En C#, los identificadores generalmente se abstraen como detalles de implementación y, en su lugar, se le proporciona un objeto con el que interactuar. El mejor ejemplo de uno que se me ocurre es el (ahora en desuso) FileStream.Handle propiedad:

public virtual IntPtr Handle { get; }

contestado el 22 de mayo de 12 a las 15:05

Después de pensar tu respuesta. Tenía un gran sentido para mí en este momento. Mango es un término más general. ¿Podría verificar esto? Un puntero debe tener una dirección de memoria para ser llamado puntero. Manejar es un término más general y no tiene que contener una dirección de memoria, sino cualquier valor entero que el kernel pueda entender. Entonces, un identificador puede almacenar un 1234545 que no es una dirección de memoria, pero el kernel usa ese número para identificar un archivo en una tabla, tal vez. Pero Handle también puede almacenar direcciones de memoria y también puede usarse como puntero. ¿Está bien? - Tarik

Suena bien. Técnicamente, un identificador no tiene que ser un número entero; puede ser de cualquier tipo. A veces, las bibliotecas devolverán un puntero para usarlo como identificador, pero es mejor tratarlo como un valor opaco y nunca quitarle la referencia. - sean tu

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.