Como lidar com tipos "repetidos"? [RESOLVIDO]

1. Como lidar com tipos "repetidos"? [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 23/11/2022 - 02:31h

Olá, alguém sabe se existe um design pattern ou outra técnica de programação pra lidar com dois tipos diferentes mas que fazem coisas parecidas?
Por exemplo: tenho um tipo Ogre::Vector3 que representa um vetor matemático e um outro que é uma classe clamada de Vector3d que é outro vetor matemático.

No caso, eu quero saber qual o melhor método pra lidar com isso? Porque nas libs que tô usando, cada uma implemneta suas próprias estruturas de dados mas que são generalizações das mesmas coisas, como Octrees, quaternions, matrizes etc. É uma bagunça tremenda!

Tenho acesso ao código de ambas, sendo a Ogre a principal lib.
Eu tava pensando em criar uma função para apenas converter de um tipoA para o B ou do B para o A, mas não sei se isso diminuiria a sensação de gambiarra rsrsrs.

Alguma ideia do que fazer neste caso?


https://nerdki.blogspot.com/ acessa ai, é grátis


  


2. MELHOR RESPOSTA

leandro peçanha scardua
leandropscardua

(usa Ubuntu)

Enviado em 23/11/2022 - 20:45h


SamL escreveu:


leandropscardua escreveu:


Se for código orientado a objetos em algum lugar deve haver uma interface ou uma classe abstrata que serve de base para todas as classes derivadas. Vc pode definir a variável com o tipo dessa classe abstrata e depois converter conforme o uso.

Ai é que tá a queda do gato porque pulo ele errou rsrsrs No caso, as duas classes não derivam da mesma, são duas classes separadas de duas libs diferentes.
Acho que o jeito é tratar com uma função pra cada conversão. Não quero fazer mas vai servir por enquanto. Valeu.


https://nerdki.blogspot.com/ acessa ai, é grátis

Se elas não estão na mesma hierarquia então vc pode criar um " adapter".
Uma classe base abstrata e uma subclasse para cada. Dentro de cada subclasse terá um objeto encapsulado. Se as classes já tiverem os mesmos nomes vc repete na classe mãe, senão vc cria uma "api".


3. Re: Como lidar com tipos "repetidos"? [RESOLVIDO]

leandro peçanha scardua
leandropscardua

(usa Ubuntu)

Enviado em 23/11/2022 - 09:42h


Se for código orientado a objetos em algum lugar deve haver uma interface ou uma classe abstrata que serve de base para todas as classes derivadas. Vc pode definir a variável com o tipo dessa classe abstrata e depois converter conforme o uso.


4. Re: Como lidar com tipos "repetidos"? [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 23/11/2022 - 11:27h


leandropscardua escreveu:


Se for código orientado a objetos em algum lugar deve haver uma interface ou uma classe abstrata que serve de base para todas as classes derivadas. Vc pode definir a variável com o tipo dessa classe abstrata e depois converter conforme o uso.

Ai é que tá a queda do gato porque pulo ele errou rsrsrs No caso, as duas classes não derivam da mesma, são duas classes separadas de duas libs diferentes.
Acho que o jeito é tratar com uma função pra cada conversão. Não quero fazer mas vai servir por enquanto. Valeu.


https://nerdki.blogspot.com/ acessa ai, é grátis


5. Re: Como lidar com tipos "repetidos"? [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 24/11/2022 - 02:39h


leandropscardua escreveu:


SamL escreveu:


leandropscardua escreveu:


Se for código orientado a objetos em algum lugar deve haver uma interface ou uma classe abstrata que serve de base para todas as classes derivadas. Vc pode definir a variável com o tipo dessa classe abstrata e depois converter conforme o uso.

Ai é que tá a queda do gato porque pulo ele errou rsrsrs No caso, as duas classes não derivam da mesma, são duas classes separadas de duas libs diferentes.
Acho que o jeito é tratar com uma função pra cada conversão. Não quero fazer mas vai servir por enquanto. Valeu.


https://nerdki.blogspot.com/ acessa ai, é grátis

Se elas não estão na mesma hierarquia então vc pode criar um " adapter".
Uma classe base abstrata e uma subclasse para cada. Dentro de cada subclasse terá um objeto encapsulado. Se as classes já tiverem os mesmos nomes vc repete na classe mãe, senão vc cria uma "api".

Boa ideia Leandro! Vou já criar uns exemplos aqui pra visualizar melhor.
Obrigado.


https://nerdki.blogspot.com/ acessa ai, é grátis


6. Re: Como lidar com tipos "repetidos"? [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 28/11/2022 - 03:17h

Sei que o tópico já está marcado como resolvido, mas eu comecei a escrever uma resposta dias atrás, que acabei não enviando antes porque me faltou tempo de terminar. Envio-a agora, na esperança de que possa ser útil.


Na medida do possível, seria bom evitar misturar uso muito frequente de objetos de tipos semelhantes, porém distintos e não-relacionados entre si, no mesmo programa. Tem certeza de que não dá para preferir um tipo, em relação ao outro? O que justificaria usar ambos ao mesmo tempo?

Solução perfeita na existe, então o que você teria de fazer dependeria de algumas perguntas, tais como:

  • É realmente necessário ter cada um dos tipos?
  • Para cada tipo, ele é usado integralmente e de modo significativo, ou apenas usam-se apenas alguns de seus membros espradicamente e isoladamente?
  • É simples e barato converter um tipo no outro?
  • Converter do tipo1 para o tipo2 é mais simples e barato do que converter do tipo2 para o tipo1?
  • Que informação importante seria perdida com as respectivas conversões de um tipo no outro?
  • Quão frequentemente teriam de ser feitas as conversões em cada sentido?
  • Operações que eventualmente usassem o valor convertido poderiam usar r-values, ou todas as conversões teria de ser explicitamente guardadas numa variável?
  • Após uma conversão de tipo, eu poderia executar várias operações antes de converter de volta, ou teria de converter de volta para o tipo original após cada operação com o tipo convertido?
  • Valeria a pena usar um dos tipos como classe base para um tipo derivado mais do que outro tipo (por exemplo: um deles tem mais funções virtuais do que outro, particularmente um destrutor virtual, permitindo melhor polimorfismo)?
  • Eventuais coleções de objetos poderiam ser polimórficas, ou usariam objetos concretos?

Não conheço nenhuma das bibliotecas que você mencionou, mas até para implementar a sugestão dada acima pelo Leandro, acima, seria interessante responder primeiro as questões acima.

Veja alguns esqueletos de solução, que podem ser mais ou menos adequados, a depender das respostas.

// Funções conversoras de tipos entre os tipos X e Y.
X to_X(const Y &y){ return X(/* alguma computação usando membros de y */); }
Y to_Y(const X &x){ return Y(/* alguma computação usando membros de x */); }

void f(){
X x;
/* ... */
func_with_X_param(x);
func_with_Y_param_by_value(to_Y(x));
Y y=to_Y(x);
func_with_Y_pointer_param(&y);
x=to_X(y);
/* ... */
}

// X facilita o polimorfismo, com funções virtuais que eu posso estender, então
// crio uma classe derivada my_X que herda de X e contém um Y.
class my_X: public X {
private:
mutable Y y_; // declaro como mutable para poder recalcular y_
// a partir de outros membros, mesmo em objetos que
// sejam logicamente constantes.
mutable bool outdated_y;

public:
my_X(/* parâmetros típicos de X (e talvez de Y) */):
X(/* parâmetros típicos de X */),
y_(/* parâmetros típicos de Y (ou calculados pelos de X) */),
outdated_y(false)
{
/* Ajustes dos parâmetros herdados de X e do campo y_. */
}

// Força atualização do campo do tipo Y.
void update_y(){
/* Ajusta o valor de y_ de acordo com os campos herados de X. */
outdated_y=false;
}

// Getter do valor de y_.
// Vale-se do fato de y_ ser mutable para recalculá-lo, caso
// necessário, mesmo que o objeto esteja identificado como constante.
Y y() const {
if(outdated_y){
/* Ajusta o valor de y_ de acordo com os campos herados de X. */
outdated_y=false;
}
return y_;
}

/* Setter para o valor de y_. */
void y(/* Parâmetros que alteram y_ */){
y_=Y(/* alguma coisa em função dos parâmetros */);
/* Recalcula/atualiza atributos herdados de X. */
}

// Função virtual herdada de X.
void virt_func(/* argumentos */) override {
X::virt_func(/* argumentos (talvez levando y_ em consideração, se estiver atualizado). */);
outdated_y=true; // Apenas marca como desatualizado (só calcula
// novamente quando precisar; mas você pode
// optar por fazer atualizando sempre).
}
};

void func_using_Y(const Y &){ }

void func(){
std::vector<std::shared_ptr<X>> collection;
collection.emplace_back(new X);
collection.emplace_back(new my_X(/* ... */));
/* ... */
for(auto &spx: collection){ // ‘spx’ é de “Shared Pointer para X”.
spx->virt_func(/* ... */); // Chama função virtual; se o objeto for
// do tipo my_X, chama my_X::virt_func().
if(const my_X *pmx=dynamic_cast<my_X *>(spx.get()); pmx){
func_using_Y(pmx->y()); // Sendo o ponteiro mx para um objeto cons-
// tante, chama o getter, que é constante
// (mas como o campo y_ é mutable, o getter
// pode eventualmente recalcular seu valor).
}
/* ... */
spx->non_virt_func(/* ... */); // Ao chamar uma função de X que não é
// virtual, tal função não vai saber
// que alguns objetos (do tipo my_X)
// têm campos adicionais.
if(my_X *pmx=dynamic_cast<my_X *>(spx.get()); pmx){
pmx->update_y(); // Força atualização de y_, uma vez que a cha-
// mada a non_virt_func() seguramente não atua-
// lizou os campos que não fazem parte de X.
}
}
}



... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)


7. Re: Como lidar com tipos "repetidos"? [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 29/11/2022 - 23:20h

@Paulo
Desculpa ai a demora em te responder.

Então, creio que dessa forma seja mais simples, digo, priorizar um tipo ao invés do outro. Até porque um dos tipos só é usado para a lib de saída (lib gráfica), enquanto que o outroé o que fica mais em uso no processamento. Por isso acho realmente mais sensato priorizar esse tipo.

Obrigado ai pelas ideias.

https://nerdki.blogspot.com/ acessa ai, é grátis






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts