2010-02-25 22 views
8

Esto podría ser una pregunta tonta para algunos de ustedes y tal vez hice esta pregunta mal, porque soy nuevo en C++. Pero noté que cuando trabajas en muchas aplicaciones win32, usas muchos recursos que son punteros. ¿Por qué siempre debe adquirir un puntero de objetos? ¿Por qué no iniciar una nueva instancia de la clase? y hablando de eso, me doy cuenta en la mayoría de los casos que nunca inicias un objeto nuevo, sino que siempre recurres a métodos que devuelven ese puntero. ¿Qué pasa si ese puntero se está utilizando en otro lugar? no podrías estropear algo si cambias ese puntero y lo estás usando en otro lado.aplicación win32 no están tan orientadas a objetos y ¿por qué hay tantos punteros?

Respuesta

24

Las API de Windows se diseñaron para C, que era y sigue siendo el lenguaje más utilizado para la programación del sistema; Las API C son el estándar de facto para las API del sistema, y ​​para esto casi todos los demás lenguajes tenían y tienen alguna forma de llamar a las funciones C externas, por lo que escribir una API C ayuda a ser compatible con otros lenguajes.

C Las API solo necesitan un ABI simple, que consiste casi en la definición de la convención de llamadas para funciones (y algo sobre el diseño de las estructuras). C++ y otros lenguajes orientados a objetos, por el contrario, requieren un ABI complejo, que debe definir cómo se colocan los objetos en la memoria, cómo manejar la herencia, cómo diseñar el vtable, cómo propagar excepciones, dónde poner datos RTTI, ... Además, no todos los lenguajes están orientados a objetos, y el uso de API pensadas para C++ con otros lenguajes no orientados a objetos puede ser un verdadero dolor (si alguna vez utilizó COM de C, ya sabe a qué me refiero).

Como acotación al margen, cuando Windows fue inicialmente diseñada C++ no estaba tan extendida en los ordenadores, y también C no se utilizó por lo tanto: de hecho, una gran parte de Windows 3.11 y muchas aplicaciones todavía estaban escritos en el montaje , ya que las limitaciones de memoria y CPU en la época eran muy ajustadas; los compiladores también eran menos inteligentes que ahora, especialmente los de C++. En las máquinas donde el ensamblaje forjado a mano solía ser la única solución, la sobrecarga de C++ era realmente inaceptable.

Por lo punteros: API de Windows utilizan casi siempre maneja , es decir puntero opaco, para ser capaz de cambiar la naturaleza subyacente de todos los recursos sin afectar a las aplicaciones existentes y detener aplicaciones a perder el tiempo con las estructuras internas. No importa si se cambia la estructura utilizada por el administrador de ventanas para representar una ventana internamente: todas las aplicaciones usan simplemente un HWND, que siempre es del tamaño de un puntero. Puede pensar en esto como una especie de modismo PIMPL.

Sin embargo, Windows está de alguna manera orientado a objetos (vea por ejemplo todo el concepto de "clase de ventana" o, en un nivel más profundo, el funcionamiento interno del kernel NT, que está fuertemente basado en el "objeto" concepto), sin embargo sus API más básicas, al ser funciones C simples, ocultan de alguna manera esta naturaleza OO. El caparazón, por otro lado, diseñado muchos años después, está escrito principalmente en C++ y proporciona una interfaz COM orientada a objetos.

Curiosamente, puede ver en COM todas las compensaciones que debe enfrentar en la construcción de una interfaz orientada a objetos interlineal pero aún en C++ sesgada: el resultado es bastante complicado, en algunos aspectos feo y no muy simple de usar cualquier idioma. Las API de Windows, en cambio, son funciones simples que generalmente se pueden llamar más fácilmente.

Si está interesado en un sistema basado en API de C++, puede echar un vistazo a Haiku; personalmente, este es uno de los aspectos por los cuales estoy bastante interesado en ese proyecto.

Por cierto, si va a hacer la programación de Win32 solo con las API, será mejor que obtenga un buen libro para acostumbrarse a estas "particularidades" y a otras expresiones de Win32. Dos conocidos son el Rector-Newcomer y el Petzhold.

+0

gracias. de todas las respuestas. tiene mucho más sentido ahora. – numerical25

+0

Gran explicación. Sin embargo, una pregunta: si Win32 está realmente orientado a objetos, ¿por qué es tan difícil obtener un puntero de instancia en una función WndProc (posiblemente el corazón de toda la API)? (cf. http://www.codeguru.com/forum/printthread.php?t=234315) –

+0

@Jared: la naturaleza más o menos orientada a objetos de la API de Win32 es una cuestión conceptual que no tiene nada que ver con el sistema de tipo C++. Las clases de ventana son un concepto del administrador de ventanas, no del idioma específico que está utilizando para acceder a las características de WM. Puede crear una correspondencia entre clases/objetos de C++ para las clases de ventana/instancias, pero en la línea de principio no tienen ninguna relación. –

1

Probablemente porque la API de Win32 es "anterior" a la programación orientada a objetos convencional, no se trata de una API de C++ en su núcleo.

5

Win32 fue diseñado para trabajar con el lenguaje C no C++.
Es por eso que verá tipos de devolución del BOOL definido en lugar de bool por ejemplo.
bool es específico de C++ y no existe en C.

Para orientado a objetos envoltura de Win32 de Microsoft ver MFC.

Un marco más nuevo de Microsoft desde entonces es .Net Framework.
El framework .Net se basa en el código administrado y no se ejecuta de forma nativa. La forma más moderna de programar la GUI en Windows es WPF o incluso Silverlight.

La forma más moderna de programar la GUI no administrada sigue siendo utilizar MFC, aunque algunas personas todavía prefieren usar Win32 directamente.

Nota trabajar con punteros no es específico de C, todavía es muy común en C++.

+2

MFC es demasiado viejo y mal diseñado, no recomendaría usarlo ... – dimsuz

+1

@dpimka: El póster pregunta específicamente por Win32. MFC no está lejos de Win32 y vale la pena mencionarlo en ese contexto. –

+3

MFC sigue siendo la _official_OO manera de hacer Windows en C++, ¿no? –

4

La primera razón es porque pasar punteros es barato. Los punteros son 4 bytes en x86 y 8 bytes en x64. Si bien la estructura o clase a la que apunta puede ocupar mucho más en la memoria. Así que instanciar una clase significa reservar nueva memoria una y otra vez. Esto no es eficiente desde la velocidad y el consumo de memoria POV.

Otra forma es pasar referencias a objetos o punteros inteligentes o construcciones similares. Pero la api win32 fue diseñada en la era C, así que aquí es donde está hasta ahora;)

En cuanto a posibles problemas con los punteros, es posible, por supuesto. Pero la mayoría de las veces su tiempo de vida se establece explícitamente en la API (si no es obvio).

-3

Para comprender los indicadores, es posible que desee leer the CPlusPlus.com tutorial on pointers.

+0

Entiendo los punteros. Simplemente no entiendo por qué C usó tantos de ellos. En todo caso, los recursos para comprender los programas del sistema WIN32 ayudarían a – numerical25

0

Es casi como si tuviera que probar una de las muchas envolturas OO. Como MFC o .net.

+0

.Net no es un contenedor Win32. –

+2

¿Qué puede hacer .net que no está en el nivel inferior API – rerun

+1

Soy desarrollador de C++ principalmente, pero incluso puedo admitir que .Net permite un desarrollo innegablemente más rápido y menos código propenso a errores. Por no mencionar menos código sin procesar para mantener. –

0

La API de Windows es simple C antigua, de ahí el uso de punteros en todas partes. Además, la razón por la que le pides a Windows un nuevo puntero es porque Windows necesita hacer un seguimiento de todos los objetos ... asigna cosas y te indica un puntero (o algunas veces solo un ID numérico) para que puedas trabajar con ellos.

7

Porque Win32 Api está escrito en C simple, no en C++. Entonces, cualquier programa en casi cualquier idioma puede hacer llamadas a esas API.

Además, no hay un mecanismo simple para usar objetos en diferentes módulos y en diferentes idiomas. Es decir. no puede exportar la clase C++ a python. Por supuesto, hay tecnologías como OLE/COM, pero todavía están escritas en la llanura C. Y están un poco complicadas de usar.

Por otra parte, las llamadas a las funciones C simples están estandarizadas. Entonces puede llamar rutinas desde DLL o lib estática en cualquier idioma.

0
  • Tener funciones C como API permite que los programadores C y C++ lo usen.
  • Las API de Windows se remontan a hace mucho tiempo: C era famoso durante esos días.

Todo el HWND, MANGO, HDC son sino un débil intento de hacer, tipos de datos como objetos-Sujeta (usando struct). C FAQ tiene una pregunta sobre esto ->http://c-faq.com/struct/oop.html.

+2

Tener funciones C permite que la mayoría de los lenguajes, incluyendo Python, Haskell y C#, también llamen a Win32. :) – Macke

+0

+1 para mencionar sobre los otros idiomas también, C tiene esa genericidad cuando se trata de ABI :) – legends2k

Cuestiones relacionadas