我有6個類的故事:3個託管和3個本機。在C++/CLI中通過包裝器(派生託管類)調用派生本機類的重寫方法
3個託管類是ManagedChildA,ManagedChildB和ManagedParent。
ManagedChildA,ManagedChildB都從ManagedParentA繼承。
3個本地類是NativeChildA,NativeChildB和NativeParent。
NativeChildA,NativeChildB都從NativeParentA繼承。
此外,ManagedChildA包裝NativeChildB,ManagedChildB包裝ManagedChildB和ManagedParentA包裝NativeParentA。
現在,這裏的故事gows歪:
ManagedParentA有包裝NativeParentA的NativeExecute)稱爲ManagedExecute的方法(()。當這個方法被調用時,一切都運行平穩。 ()包裝NativeChildA :: NativeExecute()和ManagedChildB :: ManagedExecute()包裝NativeChildB :: NativeExecute(),NativeChildB,ManagedChildB重寫ManagedExecute()以提供它們自己的實現。
例如,當調用ManagedChildA的重寫ManagedExecute()時,NativeChildA :: NativeExecute()會被調用,儘管存在System.AccessViolation錯誤。也就是說,找不到NativeChildA的原始父指針。
我想指針已經從原來的地址移開。我在互聯網上閱讀時,必須指出防止垃圾收集器(GC)移動內存,但我不知道該如何固定,因爲異常會在本機級別拋出。任何有用的提示?
實施例:
//C++ -native classes
class NativeFoo
{
public:
NativeFoo(): tested(true){}
virtual void execute()
{
std::cout << "Native Foo" << std::endl;
}
protected:
bool tested;
};
class NativeBarA :NativeFoo
{
public:
NativeBarA(): NativeFoo(){}
void execute()
{
std::cout << "Native Bar A" << std::endl;
}
};
class NativeBarB : public NativeFoo
{
public:
NativeBarB() :NativeFoo(){}
void execute()
{
std::cout << "Native Bar B" << std::endl;
}
};
//CLI interface
public interface class IExecutable
{
public:
Execute();
}
//C++-CLI classes
public ref class ManagedFoo: public IExecutable
{
private:
NativeFoo* impl;
public:
ManagedFoo(): impl(NULL)
{
impl = new NativeFoo();
}
void __clrcall Execute()
{
impl->execute();
}
};
public ref class ManagedBarA: public ManagedFoo
{
private:
NativeBarA* impl;
public:
ManagedBarA(): ManagedFoo(), impl(NULL)
{
impl = new NativeBarA();
}
void __clrcall Execute() override
{
impl->execute();
}
};
public ref class ManagedBarB: public ManagedFoo
{
private:
NativeBarB* impl;
public:
ManagedBarB(): ManagedFoo(), impl(NULL)
{
impl = new NativeBarB();
}
void __clrcall Execute() override
{
impl->execute();
}
};
//Calling code
[STAThread]
static void Main()
{
ManagedFoo^ mfoo = gcnew ManagedFoo();
ManagedBarA mbarA = gcnew ManagedBarA();
ManagedBarB mbarB = gcnew ManagedBarB();
mfoo->Execute(); //OK
mbarA->Execute(); //Error. Debugger sees value of tested as false
mBarB->Execute(); //Error
}
指向本機類的指針不會移動,這不是問題。你能告訴我們短代碼展示這個問題嗎? – svick
通過在派生類中添加具有相同名稱的成員變量來隱藏基類成員變量是一個可怕的想法。你可能想要的是一個getter函數,它將基類成員轉換爲派生類型。 –
真正的本,但如果我只想通過接口工作呢?也就是,而不是:mbarA-> Execute(),我想使用iexec-> Execute(),其中iexec是任何實現IExecutable類的實例變量? – reexmonkey