“Conocimiento Programación>C /C + + Programming

¿Cuáles son las diferencias clave entre la estructura c y la clase, cómo afectan la implementación del diseño de los programas orientados a objetos en C?

2012/1/30
Desglosemos las diferencias clave entre las estructuras C y las clases de C ++, y cómo esas diferencias afectan el diseño y la implementación de programas orientados a objetos en C y C ++.

Structs C frente a C ++ Clases:diferencias clave

| Característica | C struct | Clase C ++ | Impacto en OOP |

| -------------------- | ---------------------------------------------- | ---------------------------------------------- | ----------------- |

| Acceso predeterminado | `público` (se puede acceder a los miembros de forma predeterminada) | `Private` (los miembros son inaccesibles por defecto) | Encapsulación |

| Funciones miembros (métodos) | No permitido directamente. Puede simularlos usando punteros de función. | Permitido. Las clases pueden tener métodos (funciones) que funcionan con los datos de la clase. | Encapsulación, comportamiento |

| herencia | No compatible. | Compatible (herencia única y múltiple). | Reutilización, polimorfismo |

| polimorfismo | No compatible directamente. Requiere implementación manual (por ejemplo, utilizando punteros de función y `void*`). | Compatible (funciones virtuales, clases abstractas, interfaces). | Flexibilidad, extensibilidad |

| constructores/destructores | No compatible. La inicialización generalmente realizada con funciones de asignación o inicialización. | Apoyado. Los constructores inicializan objetos, los destructores limpian. | Gestión de recursos |

| sobrecarga del operador | No compatible. | Apoyado. Permite que los operadores (+, -, *, ==, etc.) se redefinan para objetos de clase. | Expresividad |

| plantillas | No compatible. | Apoyado. Permite la programación genérica (crear clases que pueden funcionar con diferentes tipos de datos). | Reutilización del código |

| Asignación de memoria | Típicamente utilizado para asignación estática o asignación de pila. Se puede usar con memoria asignada dinámicamente a través de punteros. | Igual que las estructuras. Generalmente preferido en contextos de objetos para crear objetos en el montón para utilizar el polimorfismo. | Gestión de la memoria |

En detalle:

1. Control de acceso (encapsulación):

- c estructuras: Todos los miembros de una estructura C son `públicas 'de forma predeterminada. Esto significa que cualquier parte de su código puede acceder directamente y modificar los datos dentro de la estructura. No hay una forma incorporada de ocultar datos internos o restringir el acceso.

- C ++ clases: El especificador de acceso predeterminado para una clase C ++ es `privado`. Esto significa que, por defecto, las variables y funciones de los miembros solo se pueden acceder desde la clase misma o desde sus clases/funciones de amigos. Utiliza palabras clave `públicas`,` protegidas` y 'privadas' para controlar la visibilidad de los miembros de la clase. Esto es crucial para encapsulación , uno de los principios centrales de OOP.

2. Funciones miembros (métodos):

- c estructuras: Las estructuras C * no pueden * contener directamente las funciones (métodos) como miembros. Para asociar las funciones con una estructura, generalmente usa punteros de funciones como miembros de la estructura. Este es un enfoque más indirecto y menos integrado.

- C ++ clases: Las clases * pueden * contener funciones de miembros (métodos). Estos métodos operan en los datos dentro de la clase y proporcionan una forma de interactuar y manipular el estado del objeto. Esto combina los datos y las funciones que operan en él, mejorando la organización y la capacidad de mantenimiento.

3. herencia:

- c estructuras: C Las estructuras * no * admiten la herencia. No puede crear una nueva estructura que herede a los miembros de una estructura existente.

- C ++ clases: Clases C ++ * do * Apoya la herencia. Esto le permite crear nuevas clases (clases derivadas o subclases) que hereden las propiedades y comportamientos de las clases existentes (clases base o superclase). Esto promueve la reutilización del código y le permite modelar las relaciones entre los objetos (por ejemplo, una clase de 'perro' heredadora de una clase 'animal'). También puede usar múltiples herencias (heredar de múltiples clases base).

4. polimorfismo:

- c estructuras: Las estructuras C no tienen soporte directo para el polimorfismo (la capacidad de un objeto para asumir muchas formas). Puede*simular*polimorfismo en C usando punteros de función y `void*`, pero requiere más codificación manual y es menos elegante. Básicamente, crea una tabla de punteros de función y selecciona la función apropiada para llamar en función del tipo de objeto.

- C ++ clases: C ++ proporciona soporte incorporado para el polimorfismo a través de:

- Funciones virtuales: Declarado con la palabra clave `virtual` en la clase base. Cuando se llama a una función virtual a través de un puntero o referencia a un objeto de clase base, la función real que se ejecuta se determina en tiempo de ejecución en función del tipo * real * del objeto (despacho dinámico).

- Clases abstractas: Una clase con al menos una función virtual pura (declarada como `=0`). Las clases abstractas no se pueden instanciar directamente, pero definen una interfaz que las clases derivadas deben implementar.

5. constructores y destructores:

- c estructuras: Las estructuras C no tienen constructores o destructores. La inicialización se realiza típicamente asignando valores a los miembros de la estructura después de declararse la estructura, o utilizando funciones de inicialización. La limpieza (liberar memoria asignada dinámicamente) también debe realizarse manualmente.

- C ++ clases: Las clases de C ++ tienen constructores (funciones especiales de miembros que se llaman automáticamente cuando se crea un objeto de la clase) y destructores (funciones de miembro especiales que se llaman automáticamente cuando se destruye un objeto). Los constructores se utilizan para inicializar los miembros de los datos del objeto, y los destructores se utilizan para liberar cualquier recurso que el objeto posee (por ejemplo, memoria asignada dinámicamente).

6. Sobrecarga del operador:

- c estructuras: La sobrecarga del operador no es compatible con C. No puede redefinir el significado de los operadores (como +, -, ==) para estructuras.

- C ++ clases: C ++ le permite sobrecargar a los operadores para objetos de clase. Esto significa que puede definir lo que significa agregar dos objetos de su clase juntos, compararlos para la igualdad, etc. Esto puede hacer que su código sea más expresivo y más fácil de leer.

7. Plantillas:

- c estructuras: C no tiene plantillas.

- C ++ clases: C ++ admite plantillas, que le permiten escribir un código genérico que puede funcionar con diferentes tipos de datos sin tener que reescribir el código para cada tipo. Esta es una característica poderosa para la reutilización de código.

Impacto en la implementación del diseño de programas orientados a objetos en C:

Debido a estas limitaciones, escribir programas verdaderamente orientados a objetos en C es * significativamente * más desafiante y requiere un enfoque diferente. Debe implementar manualmente muchas de las características integradas en las clases de C ++. Así es como puede abordar el diseño de OOP en C:

1. Emular la encapsulación:

- Use la palabra clave 'static` para limitar el alcance de las variables y las funciones al archivo actual. Esto proporciona una forma de esconder información, pero no es tan robusta como el 'Privado' de C ++.

- Use las convenciones de nomenclatura (por ejemplo, prefijo miembros "privados" con un subrayador:`_private_member`) para indicar qué miembros están destinados a ser internos. Esto se basa en la disciplina del programador.

2. Métodos de simulación:

- Defina funciones que tomen un puntero a la estructura como su primer argumento (el "este" equivalente de puntero). Estas funciones actúan como métodos para la estructura.

`` `C

typedef struct {

int x;

int y;

} Punto;

Void Point_move (Point *P, Int Dx, int dy) {// "Método" para el punto

p-> x +=dx;

p-> y +=dy;

}

`` `` ``

3. imitando la herencia:

- Composición: Incrustar una estructura dentro de otra estructura. Esto le brinda una relación "HA-A" (por ejemplo, un `Car` tiene un 'motor').

`` `C

typedef struct {

int Horsepower;

// ...

} Motor;

typedef struct {

Motor de motor; // coche * ha-a * motor

int num_wheels;

} Auto;

`` `` ``

- "herencia" (manual): Incluya la estructura base como el primer miembro de la estructura derivada. Esto asegura que los miembros de la estructura base se presenten en la memoria antes de los miembros de la estructura derivada. Luego puede lanzar un puntero a la estructura derivada a un puntero a la estructura base (pero esto requiere una gestión de memoria cuidadosa y es propensa a errores).

`` `C

typedef struct {

int ancho;

int altura;

} Rectángulo;

typedef struct {

Base rectangular; // "Hereda" del rectángulo (primer miembro)

int color;

} Coloredrectangle;

void printrectanglelea (rectangle *rect) {

printf ("área:%d \ n", rect-> ancho * rect-> altura);

}

Coloredrectangle cr ={{10, 5}, 0xff0000}; // Inicializar la estructura anidada

printrectanglerea ((rectángulo*) y cr); // válido, ya que el rectángulo es el primero en la memoria

`` `` ``

4. Fakeando polimorfismo:

- Use punteros de función dentro de la estructura para apuntar a diferentes implementaciones de la misma función, basadas en el tipo de objeto. Esto es similar al patrón de estrategia. Debe mantener manualmente una tabla de punteros de función.

`` `C

forma typedef struct {

int x;

int y;

void (*dibujar) (forma de estructura*); // Función puntero para dibujar

} Forma;

void drawcircle (forma *s) {

printf ("Círculo de dibujo en ( %d, %d) \ n", s-> x, s-> y);

}

void drawSquare (forma *s) {

printf ("Dibujo cuadrado en ( %d, %d) \ n", s-> x, s-> y);

}

Shape Circle ={10, 20, DrawCircle};

Shape Square ={30, 40, DrawSquare};

circle.draw (&círculo); // Llamas a DrawCircle

Square.Draw (&Square); // llama a dibujarsquare

`` `` ``

5. Gestión de memoria manual:

- Dado que las estructuras C no tienen constructores y destructores, debe gestionar cuidadosamente la asignación y el traficiamiento de memoria utilizando 'Malloc` y' Free`. No hacerlo conducirá a fugas de memoria.

En resumen:

- Las estructuras C son estructuras de datos más simples con características limitadas. Son adecuados para situaciones en las que solo necesita agrupar datos relacionados.

- Las clases de C ++ proporcionan características potentes para la programación orientada a objetos, incluida la encapsulación, la herencia, el polimorfismo, los constructores, los destructores, la sobrecarga del operador y las plantillas.

-Si bien * puede * implementar conceptos orientados a objetos en C utilizando estructuras, punteros de funciones y gestión de memoria manual, es significativamente más complejo, propenso a errores y menos mantenible que usar clases de C ++. Básicamente, está reimplementando las características que C ++ proporciona de forma nativa.

Cuándo usar estructuras C en lugar de clases C ++

Hay ciertas situaciones en las que el uso de una estructura C, incluso en un programa C ++, podría ser beneficioso:

1. Tipos de datos antiguos (POD): Cuando tiene una estructura de datos simple que solo contiene datos y no requiere ningún método o comportamiento especial, una estructura de POD puede ser más eficiente. Una estructura de POD se puede copiar, comparar y serializar trivialmente sin ningún código especial. C ++ ofrece rasgos de tipo `std ::is_trivial` y` std ::is_standard_layout` para determinar si un tipo tiene estas propiedades.

2. interoperabilidad con código C: Si necesita interactuar con el código C existente, usar las estructuras C es a menudo la forma más fácil de pasar datos entre los dos idiomas. C ++ puede usar directamente las estructuras C, mientras que las clases de C ++ con características complejas (como constructores, funciones virtuales, etc.) no son directamente compatibles con C.

3. Abstracción de programación/hardware de bajo nivel: En la programación de bajo nivel (por ejemplo, controladores de dispositivos, sistemas integrados), es posible que deba controlar con precisión el diseño de memoria de sus estructuras de datos. Las estructuras C le brindan más control sobre esto en comparación con las clases de C ++, donde el compilador podría agregar miembros ocultos (como un puntero de tabla de funciones virtuales).

4. Secciones críticas de rendimiento: Aunque los compiladores modernos de C ++ son altamente optimizantes, las estructuras POD a veces pueden ofrecer una ligera ventaja de rendimiento en secciones de código muy críticas de rendimiento porque carecen de la sobrecarga asociada con clases (como llamadas de funciones virtuales). *Sin embargo*, esta diferencia a menudo es insignificante y el buen código C ++ puede funcionar igual de bien, si no mejor.

En conclusión :

Si bien C puede simular principios orientados a objetos, C ++ está diseñado para facilitarlos directamente. C ++ ofrece herramientas poderosas para la encapsulación, la herencia y el polimorfismo, simplificando el diseño orientado a objetos en comparación con el enfoque más manual requerido en C. Si su proyecto se beneficia de los principios centrales de OOP, C ++ es la opción más adecuada. Las estructuras C se usan mejor en proyectos C ++ cuando se necesita interacción de código directo o al crear estructuras puramente centradas en datos.

C /C + + Programming
Cómo descargar y almacenar los medios de comunicación con el iPhone SDK
Cómo organizar una lista de Uso Las estructuras en C + +
Cómo convertir Celsius a Fahrenheit en C + + sin formatear el decimales
Cómo utilizar el control de la página en el iPhone SDK
Visual C Component Object Model Tutorial
¿Qué es la ejecución con respecto al lenguaje c?
Cómo realizar la asignación de memoria dinámica en C + +
Cómo crear un CAB en Windows Mobile
Conocimiento de la computadora © http://www.ordenador.online