1
votes

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...
    }
}
1

1 Answers

-1
votes

You may write up a virtual method CreateObject in MScatterer and implement it in derived classes. The overridden CreateObject would create instance of target classes. There is no need to have GetType method.