我有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