Considere esta hierarquia de classes (simplificada) em uma fonte c++ 98 ( godbolt ):
class Shape
{
public:
virtual class CurvilinearShape as_curvilinear_shape() const =0;
};
class CurvilinearShape : public Shape
{
// ...
public:
virtual CurvilinearShape as_curvilinear_shape() const
{
return *this;
}
};
class PolygonShape : public Shape
{
// ...
public:
virtual CurvilinearShape as_curvilinear_shape() const
{
CurvilinearShape curv_shape;
// Convert...
return curv_shape;
}
};
A PolygonShape
pode ser facilmente convertido em um arquivo CurvilinearShape
. A razão que levou a essas duas classes distintas é que a possui uma descrição simplificada que pode ser processada por máquinas mais simples, enquanto as mais avançadas podem processar o
descritor PolygonShape
mais genérico :CurvilinearShape
void work_curvilinear_shape(CurvilinearShape const&);
Neste caso é muito útil processar uma sequência de Shape
itens base sem se preocupar com o descritor real utilizado, a função de membro virtual as_curvilinear_shape()
foi introduzida apenas para isso:
#include <vector>
int main()
{
std::vector<Shape*> shapes;
for(std::vector<Shape*>::const_iterator it=shapes.begin(); it!=shapes.end(); ++it)
{
work_curvilinear_shape( (*it)->as_curvilinear_shape() );
}
}
Isso funciona, mas tem o problema da construção desnecessária de cópias que ocorre cada vez que CurvilinearShape::as_curvilinear_shape()
é chamado (aliás, na maioria das vezes).
Embora este pareça um caso de uso bastante comum, não consigo encontrar um nome para ele, você conhece? Estou procurando uma abordagem melhor que evite cópias desnecessárias caso o item já seja uma CurvilinearShape
instância, talvez um de vocês possa me colocar no caminho certo?
Uma solução (um tanto complicada) é fornecer
as_curvilinear_shape
a seguinte assinatura:Se já estiver no formato certo, retorne
*this
e deixestorage
inalterado. Se for necessária uma conversão, atribua o resultado da conversãostorage
e retorne uma referência parastorage
.Ou você pode querer criar uma classe auxiliar e retorná-la: