W programie Go, jeśli typ ma wszystkie metody zdefiniowane przez interfejs, można go przypisać do tej zmiennej interfejsu bez jawnego dziedziczenia z niego.Czy można naśladować interfejs Go w C/C++?
Czy można naśladować tę funkcję w C/C++?
W programie Go, jeśli typ ma wszystkie metody zdefiniowane przez interfejs, można go przypisać do tej zmiennej interfejsu bez jawnego dziedziczenia z niego.Czy można naśladować interfejs Go w C/C++?
Czy można naśladować tę funkcję w C/C++?
Tak. Możesz użyć czystej klasy abstrakcyjnej i użyć klasy szablonu do zawinięcia typów "implementujących" klasę abstrakcyjną, aby rozszerzyć klasę abstrakcyjną. Oto przykład 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));
}
Podejrzewam, że pewna przybliżona równoważność może być wykonalna z GObject.
Tak, oczywiście.
W rzeczywistości kod, który obsługuje interfejsy w środowisku wykonawczym jest napisany w C. http://code.google.com/p/go/source/browse/src/pkg/runtime/iface.c
Zająłem się tym w C++. Skończyło się na czymś, co działa, ale jest cyrkiem makro: https://github.com/wkaras/c-plus-plus-misc/tree/master/IFACE. Interfejs to dwa wskaźniki, jeden do obiektowania elementów danych, a drugi do odpowiednika wirtualnej tabeli (struktura wskaźników do funkcji thunk, które wywołują funkcje członkowskie). Te tabele są (niestety) generowane w czasie wykonywania. Konwersja z interfejsu do podrzędnego interfejsu wymaga wyszukiwania w trybie nieuporządkowanego_mapy, więc jest to średnio złożoność czasu O (1). W porównaniu z konwersją pochodnego wskaźnika klasy/odwołania do jednego na klasę podstawową, która jest najgorszym przypadkiem O (1).
Nie nadaje się do użytku, ale pokazuje, że interfejsy mogą być (czysto) dodane do C++ przy stosunkowo niewielkim wysiłku. Są przypadki, w których interfejsy są lepsze niż OO oparte na spadkach, a krowa jest poza stodołą, jeśli chodzi o utrzymywanie małego C++.
W pewnym sensie to właśnie robią szablony. Jeśli wywołasz funkcję z argumentami z szablonem, możesz przekazać dowolne obiekty spełniające wymagania zdefiniowane przez sposób korzystania z szablonu. – Bill