Оболочка c ++ / cli для полиморфных нативных классов - PullRequest
1 голос
/ 24 августа 2011

Мы пишем оболочку c ++ / cli для нативного кода, которая является полиморфной и хотела бы максимально расширить полиморфизм на неродную сторону.До сих пор, учитывая экземпляр класса c ++ / cli, легко получить базовый нативный класс, но проблема возникает при попытке определить, какую оболочку c ++ / cli использовать для данного экземпляра нативного класса.Было бы хорошо, если бы здесь можно было избежать оператора switch, но как?Есть ли более элегантное объектно-ориентированное решение?

Обратите внимание, что в следующем коде я использую префикс M для типов C ++ / CLI (например, FresnelScatterer является нативным классом, а MFresnelScatterer является классом-оберткой C ++ / CLI дляit).

Базовый класс 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...
    }
}

1 Ответ

0 голосов
/ 24 августа 2011

Вы можете написать виртуальный метод CreateObject в MScatterer и реализовать его в производных классах. Переопределенный CreateObject создаст экземпляр целевых классов. Нет необходимости иметь метод GetType.

...