C++ 确定由指向成员函数的指针调用的成员函数内的上下文
这个标题可能不够解释,因为这个问题很难描述 我无法更改库中的以下(简化)两种数据结构:C++ 确定由指向成员函数的指针调用的成员函数内的上下文,c++,c++-cli,member-function-pointers,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: virt
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;
}
};
现在,我想为该功能创建一个C++/CLI包装器(继承自并能够分配成员方法)。为了简单起见,省略了创建B实例的细节:
ref class WrapperB
{
public:
delegate void AMemFuncDelegate();
void AddToCollection(AMemFuncDelegate ^func, String ^identifier)
{
// Do stuff
}
};
但我遇到了一个问题,即如何允许动态创建成员函数指针
以下是我迄今为止提出的低于标准的解决方案:
- 完全忽略非托管std::vector,并在c++/cli中对其进行完全管理(详细信息未列出,但这是可能的)。缺点是C++侧没有托管函数的互操作能力(或知识)。
- 在
中定义N个成员函数,这些函数将唯一id传输到可耦合到代理的受管端。这限制了可以添加到集合中的内容的数量,并导致大量代码混乱和重复。此外,当用户调用B
时,我无法检测到删除RemoveFromCollection
(也没有虚拟析构函数)并解耦托管委托。但这在所有情况下都是一个问题FooBar
<>编辑:我在非托管端不能使用C++ 11或更高。 @ ANDYG,而C++中使用C风格的转换当然是非常糟糕的做法,我认为只要成员指针只与实际上是“代码> b/COD>”类型的对象一起使用,这应该是很好的。这里的C样式转换为
static\u cast
,因为static\u cast
可以从指向类成员的指针转换为指向其某个基类成员的指针?库实际上如何使用成员函数指针?我想它一定会以某种方式使用它作为一种回调?如果是这样的话,这个回调函数是否获得了任何信息,可以用来将它映射回某个特定的委托?@MichaelKenzel:我想显示的代码是安全的,只要它实际调用函数时,它被转换回适当的类型。@AndyG我认为没有必要进行转换。唯一需要的是,与成员指针一起使用的对象的动态类型实际上是正确的类型(B
)。至少就我的理解而言,成员指针应该有任何必要的偏移量,这个指针编码在它们的值中…@MichaelKenzel:我会的。看起来你是100%对的。谢谢你指出这一点。不知道动态类型的规则。我原以为它是未定义的,但它之所以有效,只是因为偏移量是偶然排列的;在多重继承的情况下,我认为他们不会。谢谢。@ ANDYG,但是C++中使用C风格的转换当然是非常糟糕的做法,我认为只要成员指针只与实际上是类型<代码> b/COD>的对象一起使用,就可以了。这里的C样式转换为static\u cast
,因为static\u cast
可以从指向类成员的指针转换为指向其某个基类成员的指针?库实际上如何使用成员函数指针?我想它一定会以某种方式使用它作为一种回调?如果是这样的话,这个回调函数是否获得了任何信息,可以用来将它映射回某个特定的委托?@MichaelKenzel:我想显示的代码是安全的,只要它实际调用函数时,它被转换回适当的类型。@AndyG我认为没有必要进行转换。唯一需要的是,与成员指针一起使用的对象的动态类型实际上是正确的类型(B
)。至少就我的理解而言,成员指针应该有任何必要的偏移量,这个指针编码在它们的值中…@MichaelKenzel:我会的。看起来你是100%对的。谢谢你指出这一点。不知道动态类型的规则。我原以为它是未定义的,但它之所以有效,只是因为偏移量是偶然排列的;在多重继承的情况下,我认为他们不会。谢谢
ref class WrapperB
{
public:
delegate void AMemFuncDelegate();
void AddToCollection(AMemFuncDelegate ^func, String ^identifier)
{
// Do stuff
}
};