2012-01-23 31 views
6

En Go, si el tipo tiene todos los métodos definidos por la interfaz, entonces se puede asignar a esa variable de interfaz sin heredarla explícitamente.¿Es posible imitar la interfaz Go en C/C++?

¿Es posible imitar esta característica en C/C++?

+0

En cierto sentido, eso es lo que hacen las plantillas. Si invoca una función con argumentos estructurados, puede pasar cualquier objeto que cumpla con los requisitos definidos por la forma en que usa la plantilla. – Bill

Respuesta

3

Sí. Puede usar una clase abstracta pura y usar una clase de plantilla para ajustar los tipos que "implementan" la clase abstracta para que amplíen la clase abstracta. Aquí está un ejemplo de barebones:

#include <iostream> 

// Interface type used in function signatures. 
class Iface { 
public: 
     virtual int method() const = 0; 
}; 

// Template wrapper for types implementing Iface 
template <typename T> 
class IfaceT: public Iface { 
public: 
     explicit IfaceT(T const t):_t(t) {} 
     virtual int method() const { return _t.method(); } 

private: 
     T const _t; 
}; 

// Type implementing Iface 
class Impl { 
public: 
     Impl(int x): _x(x) {} 
     int method() const { return _x; } 

private: 
     int _x; 
}; 


// Method accepting Iface parameter 
void printIface(Iface const &i) { 
     std::cout << i.method() << std::endl; 
} 

int main() { 
     printIface(IfaceT<Impl>(5)); 
} 
0

Supongo que una cierta equivalencia aproximada podría ser factible con GObject.

0

Lo apuñalé para C++. Terminé con algo que funciona, pero es un macro circo: https://github.com/wkaras/c-plus-plus-misc/tree/master/IFACE. Una interfaz son dos punteros, uno para objetos miembros de datos, y otro para el equivalente de una tabla virtual (una estructura de punteros a funciones de procesador que llaman a funciones miembro). Estas tablas (desafortunadamente) se generan en tiempo de ejecución. La conversión de una interfaz a una subinterfaz requiere una búsqueda de mapa desordenado, por lo que es O (1) la complejidad del tiempo en promedio. En comparación con la conversión de un puntero/referencia de clase derivado a uno a una clase base, que es O (1) el peor de los casos.

No es muy utilizable, pero muestra que las interfaces se pueden agregar (limpiamente) a C++ con relativamente poco esfuerzo. Hay casos en que las interfaces son mejores que las OO basadas en herencia, y la vaca está fuera del establo en lo que respecta a tratar de mantener C++ pequeño.

Cuestiones relacionadas