多态本地类的c++/cli包装器

c++/cli wrapper for polymorphic native classes

本文关键字:cli 包装 c++ 多态      更新时间:2023-10-16

我们正在为本机代码编写一个多态的c++/cli包装器,并希望将多态尽可能地扩展到非本机端。到目前为止,给定一个c++/cli类实例,很容易检索底层的本机类,但是当试图确定为给定的本机类实例使用哪个c++/cli包装器时,问题就来了。在这里避免switch语句是很好的,但是如何避免呢?有没有更优雅的面向对象解决方案?

请注意,在下面的代码中,我使用了一个前缀M来表示c++/CLI类型(例如,FresnelScatterer是一个本机类,而MFresnelScatterer是它的c++/CLI包装类)。

本地c++基类和继承类:

class Scatterer
{
public:
    ScatterType Type;
Scatterer() {}
virtual ~Scatterer() {}
ScatterType GetType() { return Type; }
    // Some virtual functions here...
};
class FresnelScatterer : public Scatterer
{
public:
// virtual function overrides
};

c++/cli基类和继承类:

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;
    }
};

一个从c++/CLI到>原生c++可以很好地工作的例子如下:

for each ( MScatterer^ mScatterer in readScene->ScattererList)
{
    m_Scene->scattererList.push_back(mScatterer->convertXMLdata());
}

但是从本机c++开始,我不知道如何教c++/CLI我的本机对象是哪种类型而不使用switch语句:

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

您可以在MScatterer中编写一个虚拟方法CreateObject,并在派生类中实现它。重写的CreateObject将创建目标类的实例。不需要GetType方法