确定指向成员函数调用的成员函数内部的上下文

时间:2019-04-10 14:13:47

标签: c++ c++-cli member-function-pointers

标题可能不够解释,因为问题很难描述。

我无法更改的库中有以下两个(简化的)数据结构:

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 ++端没有与托管函数的互操作功能(或相关知识)。
  • B中定义N个成员函数,这些成员函数将唯一的ID传输到可与委托耦合的被管理端。这限制了您可以添加到集合中的内容的数量,并且使代码混乱和重复很多。同样,当用户调用RemoveFromCollection时,我无法检测到FooBar的移除(也没有虚拟析构函数),也无法分离托管委托。但这在所有情况下都是一个问题

到目前为止,我提出的两种解决方案都不理想,我不确定是否在这里遗漏了一些东西。

编辑:我不能在非托管方面使用c ++ 11或更高版本。

0 个答案:

没有答案