2

我最近开始使用 C++/Cli 进行包装。现在我正处于一个我必须更多地了解内部结构的地步。

考虑以下代码:

Header file (ignoring .NET namespaces for this example):

public ref class BaseyClass
{
    protected:
        delegate void TestMethodDelegate(); // TestMethod delegate
        BaseyClass();                       // constructor            
        virtual void TestMethod();          // member: method
        GCHandle _testMethodHandle;         // member: method handle
};


CPP file (ignoring .NET namespaces for this example):

BaseyClass::BaseyClass()
{
    _testMethodHandle
          = GCHandle::Alloc(
                       gcnew TestMethodDelegate(this, &BaseyClass::TestMethod));
}

void TestMethod()
{
}

最终,这个类将在以后用作基类(对于 DerivedClass),并且方法“TestMethod()”被覆盖并通过委托指针从非托管代码中调用。

现在的问题是:委托将引用哪个方法?

BaseyClass::TestMethod();

或者

DerivedClass::TestMethod();

我个人认为委托将引用“BaseyClass::TestMethod()”,因为即使它被覆盖,委托也指向 BaseyClass 的(基)地址。因此,DerivedClass 不能覆盖“TestMethod”并使用来自 BaseyClass 的委托。

我只是想确定一下。感谢您的评论和启发。

4

1 回答 1

1

委托将是对派生类的 TestMethod 的引用。即使您正在传递&BaseyClass::TestMethod,这是一个虚拟方法,您也正在传递this,这是派生类型,并且在创建委托时会考虑这两者。

其他注意事项:

  • TestMethodDelegate 不需要在类定义中。更标准的方法是将委托放在类之外,就在命名空间中。(或者使用现有的内置一个,Action。)
  • 你不需要GCHandle::Alloc(我认为这就是你的意思)。相反,声明_testMethodHandleTestMethodDelegate^(或Action^)。通常,除非您与非托管代码交互,否则您不需要处理 GCHandle,并且此代码都是托管的。

这是我的测试代码:

public ref class BaseyClass
{
public:
    BaseyClass() { this->_testMethodHandle = gcnew Action(this, &BaseyClass::TestMethod); }
    virtual void TestMethod() { Debug::WriteLine("BaseyClass::TestMethod"); }
    Action^ _testMethodHandle;
};

public ref class DerivedClass : BaseyClass
{
public:
    virtual void TestMethod() override { Debug::WriteLine("DerivedClass::TestMethod"); }
};


int main(array<System::String ^> ^args)
{
    BaseyClass^ base = gcnew DerivedClass();
    base->_testMethodHandle();
    return 0;
}

输出:

DerivedClass::TestMethod

于 2012-12-13T17:54:15.530 回答