В Go, если тип имеет все методы, определенные интерфейсом, тогда он может быть назначен этой переменной интерфейса без явного наследования.Можно ли имитировать интерфейс Go в C/C++?
Можно ли имитировать эту функцию в C/C++?
В Go, если тип имеет все методы, определенные интерфейсом, тогда он может быть назначен этой переменной интерфейса без явного наследования.Можно ли имитировать интерфейс Go в C/C++?
Можно ли имитировать эту функцию в C/C++?
Да. Вы можете использовать чистый абстрактный класс и использовать класс шаблона для переноса типов «реализации» абстрактного класса, чтобы расширить абстрактный класс. Вот пример с баребонами:
#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));
}
Я предполагаю, что приблизительная эквивалентность может быть осуществима с GObject.
Да, конечно.
На самом деле код, который обрабатывает интерфейсы во время выполнения написан на C. http://code.google.com/p/go/source/browse/src/pkg/runtime/iface.c
Я взял у него удар по C++. Я закончил с чем-то, что работает, но является цирковым цирком: https://github.com/wkaras/c-plus-plus-misc/tree/master/IFACE. Интерфейс представляет собой два указателя, один для объектных элементов данных, а другой эквивалент виртуальной таблицы (структура указателей на функции thunk, вызывающих функции-члены). Эти таблицы (к сожалению) генерируются во время выполнения. Для преобразования из интерфейса в под-интерфейс требуется поиск неупорядоченного_мапа, поэтому в среднем это сложность времени O (1). По сравнению с преобразованием указателя производного класса/ссылки на один на базовый класс, который является O (1) наихудшим.
Это не очень удобно, но это показывает, что интерфейсы могут быть (чисто) добавлены в C++ с относительно небольшим усилием. Бывают случаи, когда интерфейсы лучше, чем OO на основе наследования, и корова хорошо из сарая, поскольку пытается сохранить C++ маленьким.
В некотором смысле это то, что делают шаблоны. Если вы вызываете функцию с аргументированными аргументами, вы можете передать любые объекты, которые отвечали бы требованиям, определяемым тем, как вы используете шаблон. – Bill