2010-06-24 17 views
18

? El lenguaje C++ proporciona funciones virtual. Dentro de las limitaciones de una implementación pura del lenguaje C, ¿cómo se puede lograr un efecto similar?¿Cómo se pueden implementar las funciones virtuales de C++ en C

+2

¿Por qué quieres implementar C++ nuevamente? Temas como este se pueden encontrar fácilmente en los libros y también hay muchos artículos en línea. Al hacer este tipo de preguntas, su reputación se verá afectada y las personas comenzarán a darle por hecho. Así que haz todo lo que puedas para encontrar la respuesta, y aún así no puedes preguntar :). –

+0

¿Qué estás tratando de lograr? – DRL

+0

profesor nos hizo esta pregunta –

Respuesta

29

Robados de here.

De la clase de C++ fragmento de código

class A { 
protected: 
    int a; 
public: 
    A() {a = 10;} 
    virtual void update() {a++;} 
    int access() {update(); return a;} 
}; 

un C puede derivarse. Las tres funciones miembro de C++ de class A se reescriben usando código fuera de línea (independiente) y se recopilan por dirección en una estructura llamada A_functable. Los miembros de datos de A y combinados con la tabla de funciones en una estructura C llamada A.

struct A; 

typedef struct { 
    void (*A)(struct A*); 
    void (*update)(struct A*); 
    int (*access)(struct A*); 
} A_functable; 

typedef struct A{ 
    int a; 
    A_functable *vmt; 
} A; 

void A_A(A *this); 
void A_update(A* this); 
int A_access(A* this); 

A_functable A_vmt = {A_A, A_update, A_access}; 

void A_A(A *this) {this->vmt = &A_vmt; this->a = 10;} 
void A_update(A* this) {this->a++;} 
int A_access(A* this) {this->vmt->update(this); return this->a;} 

/* 
class B: public A { 
public: 
    void update() {a--;} 
}; 
*/ 

struct B; 

typedef struct { 
    void (*B)(struct B*); 
    void (*update)(struct B*); 
    int (*access)(struct A*); 
} B_functable; 

typedef struct B { 
    A inherited; 
} B; 

void B_B(B *this); 
void B_update(B* this); 

B_functable B_vmt = {B_B, B_update, A_access}; 

void B_B(B *this) {A_A(this); this->inherited.vmt = &B_vmt; } 
void B_update(B* this) {this->inherited.a--;} 
int B_access(B* this) {this->inherited.vmt->update(this); return this->inherited.a;} 

int main() { 
    A x; 
    B y; 
    A_A(&x); 
    B_B(&y); 
    printf("%d\n", x.vmt->access(&x)); 
    printf("%d\n", y.inherited.vmt->access(&y)); 
} 

Más elaborada de lo necesario, pero logra entenderse.

+0

+1 Gran ejemplo: esto es lo más parecido posible a la traducción de tablas virtuales a C y es mucho más elegante que los programadores en C que hacen cosas como moldes de punteros de función o estructuras de fundido de indicadores de función. Todavía es voluminoso e incómodo, pero bueno, C no fue diseñado para esto. – stinky472

+1

@ stinky472: estoy de acuerdo contigo, pero cuando alguien está a punto de necesitar un código como este, simplemente no tiene sentido. Ciertos idiomas son más adecuados para ciertos problemas. – Alerty

+0

Muy cierto, pero me han obligado a trabajar en sistemas C intentando implementar OOP. Lo hicieron fundiendo estructuras con punteros de función (como casting struct A), en lugar de simplemente pasar A por polimorfismo y permitir que cada estructura tipo subclase simplemente almacenara A y le asignara direcciones de función y datos apropiados. Esto, al menos, es mucho más elegante que los indicadores de función de fundición o de fundición de estructuras. – stinky472

-1

Here es una descripción de lo que son las funciones virtuales.

No hay forma de implementar funciones virtuales en C simple, porque C no tiene noción de herencia.

Actualización: Como se discute en los comentarios a continuación, es posible hacer algo similar a las funciones virtuales en C recta utilizando las estructuras y los punteros de función. Sin embargo, si está acostumbrado a un lenguaje como C++ que tiene funciones virtuales "verdaderas", probablemente encontrará que la aproximación C es mucho menos elegante y más difícil de usar.

+1

en realidad, existe una noción de herencia en C pero no respeta el control de ACCESO aquí: http://stackoverflow.com/questions/577465/in-c-can-i-derive-a-class-from- a-struct –

+0

@Gollum: una estructura C++ no es como C struct. – Alerty

+2

No puede hacerlo directamente (falta la clase :)) - pero no es un problema implementar dicho sistema utilizando estructuras y punteros de función. – ManniAT

0

Las funciones virtuales son una característica de la orientación a objetos de C++. Se refieren a métodos que dependen de una instancia de objeto específico en lugar de qué tipo los está llevando actualmente como.

En otras palabras: si instancia un objeto como Bar, luego lo envía a Foo, los métodos virtuales seguirán siendo los que estaban en instanciación (definidos en Bar), mientras que otros métodos serán los de Foo.

Las funciones virtuales se implementan típicamente por medio de vtables (es para que investigue más;)).

Puede simular cosas similares en C utilizando estructuras como objetos de personas pobres y guardando punteros de función en ellas.

(más correctamente, las funciones no virtuales hacen que sea ambiguo, que el método de la clase debe ser tomado de, pero en la práctica creo C++ utiliza el tipo actual.)

1

@GCC .... Una función virtual se declara en la clase base de un objeto y luego se "anula" o se implementa en las subclases. es decir, digamos que tiene una clase Base de vehículo y crea dos subclases, Motocicleta y Automóvil. La clase Base declararía una función virtual de AddTires() Entonces las Subclases implementarían esta función y cada subclase la implementaría de manera diferente. Un automóvil tiene 4 ruedas, donde una motocicleta tiene 2. Sin embargo, no puedo darte la sintaxis para C o C++. Espero que esto ayude

+0

Por supuesto, mi respuesta se basa en C# y ese modelo de objetos – MikeTWebb

Cuestiones relacionadas