We are writing a c++/cli wrapper for native code that is polymorphic and would like to extend the polymorphism into the non-native side as much as possible. So far, given a c++/cli class instance it is easy to retrieve the underlying native class but the trouble comes when trying to determine which c++/cli wrapper to use for a given native class instance. It would be nice to be able to avoid a switch statement here, but how? Is there a more elegant object-oriented solution?
Note that in the following code I use a prefix of M for C++/CLI types (e.g. FresnelScatterer is a native class and MFresnelScatterer is the C++/CLI wrapper class for it).
The native c++ base class and inherited class:
class Scatterer
{
public:
ScatterType Type;
Scatterer() {}
virtual ~Scatterer() {}
ScatterType GetType() { return Type; }
// Some virtual functions here...
};
class FresnelScatterer : public Scatterer
{
public:
// virtual function overrides
};
The c++/cli base class and inherited class:
public ref class MScatterer abstract
{
public:
Scatterer* m_Scatterer;
MScatterer() {}
MScatterer(MScatterer% mscatter)
{
m_Scatterer = mscatter.m_Scatterer;
}
MScatterer(Scatterer* scatter)
{
m_Scatterer = scatter;
}
[XmlElement("The_Scatterer_Type")]
int ScattererType;
virtual void initializeXMLdata()
{
ScattererType = (int) m_Scatterer->GetType();
}
virtual Scatterer* convertXMLdata() = 0;
~MScatterer() { }
// more wrapping here
};
public ref class MFresnelScatterer : MScatterer
{
public:
MFresnelScatterer() : MScatterer() {}
MFresnelScatterer(MFresnelScatterer% mfscatter) : MScatterer(mfscatter)
{
};
MFresnelScatterer(FresnelScatterer* mfscatter) : MScatterer(mfscatter)
{
};
virtual void initializeXMLdata() override
{
MScatterer::initializeXMLdata();
// other init
}
virtual Scatterer* convertXMLdata() override
{
//Scatterer
FresnelScatterer* sca = new FresnelScatterer();
return sca;
}
};
An example where going from C++/CLI -> native C++ works nicely is here:
for each ( MScatterer^ mScatterer in readScene->ScattererList)
{
m_Scene->scattererList.push_back(mScatterer->convertXMLdata());
}
But going from native c++, I cannot see how to teach C++/CLI which type my native object is without using a switch statement:
for (uint i=0; i<m_Scene->scattererList.size(); i++)
{
switch (m_Scene->scattererList[i]->GetType())
{
case SCA_FRESNEL:
{
MFresnelScatterer^ sca = gcnew MFresnelScatterer((FresnelScatterer*) m_Scene->scattererList[i]);
sca->initializeXMLdata();
ScattererList->Add(sca);
break;
}
// other cases follow...
}
}