Dev - C++ - POO C++ Interfaz.

   
Vista:

POO C++ Interfaz.

Publicado por CRISTIAN NICOLAS (4 intervenciones) el 10/04/2016 04:40:49
Hola tenngo una consulta respecto de las interfaz.

Tengo la clase Forma y cada forma le puedo calcular el area, entonces hice una clase abstracta que se llama Calculable(para dar una idea) entonces hago que Forma implemente esta interfaz donde hereda el método darArea() de Calculable.

Ahora 2 preguntas.

La clase Forma debe tener en su firma declarada de manera virtual el método darArea()? Porque las clases hijas, Circulo, Cuadrado son las que la van a implemente y no area.


Después otra pregunta, tengo un método que quiere devolver algo que implemente esta interfaz

por ejemplo.

Calculable funcionAlgo(char cadena);

Para dar un contexto yo quiero pasarle a esta funcion algo como "cuadrado 2" donde sería la figura y cuando mi su lado o
"rectangulo 2 4" como a mi no importa que clase especificamente es, solo me interesa que le pueda pedir el area, cuando escribo esta firma me dice que el tipo Calculable no se puede resolver.

Obviamente existen otras clases que también implementan esta interfaz por eso no pongo

Forma funcionAlgo(char cadena);

Muchas gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

POO C++ Interfaz.

Publicado por Martín (65 intervenciones) el 10/04/2016 05:45:53
Hola.
La clase Forma debe tener en su firma declarada de manera virtual el método darArea()? Porque las clases hijas, Circulo, Cuadrado son las que la van a implemente y no area.

No sé qué vendría a ser que una clase tenga declarada en su firma un método, pero con respecto a si es necesario que la clase derivada Forma tenga declarado el método darArea, no, no es necesario, a menos que quieras que darArea tenga un comportamiento por defecto. Esto es: si alguna clase derivada de Area no tuviera implementado darArea, va a usar la definida en Forma.

La segunda pregunta no la entendí.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

POO C++ Interfaz.

Publicado por Cristian (4 intervenciones) el 10/04/2016 06:08:56
Primero que nada, muchas gracias por responder!

Dale voy a tratar de explicarlo mejor.


diagrama

Tengo 2 clases que implementar una interfaz que tiene el método evaluar();

Tengo una función a la que le paso una cadena tipo "hija1" y me devuelve una instancia de esa clase, pero para hacerlo de forma genérica en la función quería poner algo del estilo

Evaluable funcion(char cadena);

Osea que siempre me devuelve objetos que implementan la interfaz Evaluable porque luego a este objeto lo único que me interesa es poderle invocar el método evaluar();
Pero cuando escribo el método me tira un error del tipo "el tipo Evaluable no puede ser resuelto". Claro porque no puedo instanciar objetos de Evaluable, entonces no hay una manera de resolverlo? O debería cambiar mi diseño?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

POO C++ Interfaz.

Publicado por Martín (65 intervenciones) el 11/04/2016 02:56:21
A mí me parece bien así; sólo que la forma de tu función
1
Evaluable funcion(char cadena);
no está bien: tiene que devolver un puntero a Evaluable (en particular un unique_ptr) y el parámetro puede ser un char, o lo que quieras, pero ¿es posible que estés queriendo pasar una string como argumento a un parámetro de tipo char? ¿no, verdad?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

POO C++ Interfaz.

Publicado por Cristian (4 intervenciones) el 14/04/2016 04:10:18
No no, igual lo cambié y ahora recibe un char*

Ahora tengo otra drama, en el diagrama puse que Interfaz tiene un método abstracto:

1
+evaluar() : void.


Acá tengo tengo un problema porque en realidad cada clase que implemente la interfaz puede devolver distintas cosas. Lo pensé cambiando a :
1
+evaluar() : void*.

para hacerlo génerico pero me parece rebuscado andar casteando.

Por eso pensé lo siguiente:
1
2
3
4
5
6
7
8
template <typename T>
 
class Evaluable {
public:
	Evaluable();
	virtual ~Evaluable();
	virtual T evaluar()=0;
};



Y luego una clase por ejemplo Clase1

1
2
3
4
5
6
7
class Clase1: Evaluable<int>{
	int numero;
public:
	Clase1(std::string cadena);
	~Clase1();
	int evaluar();
};


Y así cada clase que implemente la interfaz decide que tipo de dato debe devolver y a la vez implementa la interfaz. Esto es posible? Me tirá error el compilador. Capaz sea un boludez, pero por lo pronto es posible esta clase de implementación?

Gracias!
Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

POO C++ Interfaz.

Publicado por Martín (65 intervenciones) el 14/04/2016 04:26:22
Yo te decía que para mí estaba bien esa función "funcion" que devolvía un Evaluable genérico. Sólo que podría ser de esta forma:

1
std::unique_ptr<Evaluable> funcion(std::string cadena);

Esto es lo que se llama una "factory", que te va a devolver una instancia de algún tipo de objeto derivado de Evaluable, como puntero polimórfico. Es un patrón muy usado en C++. funcion() va a tener toda la cadena de ifs donde decidir qué clase de Evaluable devolver. Si los constructores necesitan parámetros, se pasan también en funcion(), y si esos parámetros para los constructores son de distinto tipo y/o de distinta cantidad, se usa un [url]https://en.wikipedia.org/wiki/Variadic_template/url] variadic template.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

POO C++ Interfaz.

Publicado por Cristian (4 intervenciones) el 14/04/2016 04:50:37
Claro vos decís algo del estilo:


1
2
3
4
5
td::unique_ptr<Evaluable> funcion(std::string cadena){
          if (clase1) devuelvo clase1;
          if (clase2) devuelvo clase2;
         .....
}


No?

Eso ya lo pude resolver, ahora mi problema es que las clases derivadas implementan la función
1
+evaluar()
pero cada clase derivada algo distinto, entonces pensé lo anterior. Pero el compilar me tira un error.

Por las dudas coloco todos los archivos.

Evaluable.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef EVALUABLE_H_
#define EVALUABLE_H_
 
 
template <typename T>
 
class Evaluable{
public:
	Evaluable();
	virtual ~Evaluable();
	virtual T evaluar()=0;
};
 
#endif /* EVALUABLE_H_ */

Evaluable.cpp
1
2
3
4
5
#include "Evaluable.h"
 
template<typename T>
 
Evaluable<T>::Evaluable() {}


Una clase derivada. Number.
Number.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef NUMBER_H_
#define NUMBER_H_
 
#include <string>
#include "Evaluable.h"
 
class Number:public Evaluable{
	int numero;
public:
	Number(std::string cadena);
	~Number();
	int evaluar();
};
 
#endif /* NUMBER_H_ */

Number.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "Number.h"
#include <string>
#include <stdlib.h> //atoi
using namespace std;
 
Number::Number(string cadena) {
	this->numero = atoi(cadena.c_str());
}
 
int Number::evaluar(){
	return this->numero;
}
 
 
Number::~Number(){}


Una vez que pueda especificar que cada clase derivada implementa la interfaz pero el método evaluar algo distinto, aplico el patrón de diseño que mencionaste, pero no estoy pudiendo resolver esto.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

POO C++ Interfaz.

Publicado por Martín (65 intervenciones) el 14/04/2016 05:00:14
Yo creo que entonces evaluar() no es una función común a todas las clases derivadas de Evaluable, o por lo menos, no veo por qué evaluar() tiene que ser parte de la interface común cuando cada evaluar() tiene distinta signature, esa no parece ser la idea de una interface.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar