Название может быть недостаточно пояснительным, поскольку проблему трудно описать.
У меня есть следующие (упрощенные) две структуры данных в библиотеке, которые я не могу изменить:
class A;
typedef void(A::*AMemFunc)();
struct FooBar
{
AMemFunc func;
std::string identifier;
};
class A
{
private:
std::vector<FooBar *> theCollection;
public:
virtual ~A()
{
for (auto fooBar : theCollection)
{
delete fooBar;
}
theCollection.clear();
}
void AddToCollection(AMemFunc func, const std::string &identifier)
{
FooBar *newFooBar = new FooBar();
newFooBar->func = func;
newFooBar->identifier = identifier;
theCollection.push_back(newFooBar);
}
void RemoveFromCollection(const std::string &identifier)
{
for (auto collectionIt = theCollection.begin(); collectionIt != theCollection.end(); collectionIt++)
{
FooBar *currentFooBar = *collectionIt;
if (currentFooBar->identifier == identifier)
{
collectionIt = theCollection.erase(collectionIt);
delete currentFooBar;
currentFooBar = nullptr;
}
}
}
const std::vector<FooBar *> &getTheCollection() const
{
return theCollection;
}
};
Функция-член вызывается из библиотеки и находится вне моего контроля. Теперь пользователь библиотеки может создавать подклассы A и добавлять функцию-член в коллекцию следующим образом:
class B : public A
{
public:
B()
{
AddToCollection((AMemFunc)&B::Test, "MyIdentifier");
}
void Test()
{
}
};
Теперь я хочу создать оболочку C ++ / CLI для этой функции (наследование от A и возможность назначать метод-член). Подробности создания экземпляра B для простоты опущены:
ref class WrapperB
{
public:
delegate void AMemFuncDelegate();
void AddToCollection(AMemFuncDelegate ^func, String ^identifier)
{
// Do stuff
}
};
Но передо мной стоит проблема, как я мог бы разрешить динамическое создание указателей на функции-члены.
Это решения, которые я до сих пор предлагал:
- вообще игнорировать неуправляемый std :: vector и полностью управлять им в c ++ / cli (подробности опущены, но это возможно). Недостатком является то, что сторона C ++ не имеет возможностей взаимодействия (или знаний о) с управляемыми функциями.
- Определить N функций-членов в
B
, которые передают уникальный идентификатор управляемой стороне, которая может быть связана с делегатом. Это ограничивает количество вещей, которые вы можете добавить в коллекцию, и дает много беспорядка кода и дублирования. Также, когда пользователь вызывает RemoveFromCollection
, я не могу обнаружить удаление FooBar
(без виртуального деструктора) и отделить управляемый делегат. Но это действительно проблема во всех ситуациях
Оба решения, которые я придумала до сих пор, не идеальны, и я не уверен, что что-то здесь упущено.
Редактировать: я не могу использовать c ++ 11 или выше на неуправляемой стороне.