Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: HardForo en 23 Abril 2016, 03:45 am



Título: Forma segura de implementar tipo Naturales positivos
Publicado por: HardForo en 23 Abril 2016, 03:45 am
A sabiendas del problema de crear tipos unsigned int he intentado manejarlos en un programa simple pero que tenia como variables distancias, longitud de cadenas y otras magnitudes que se definen  de forma positiva.

Código
  1. typedef unsigned int longitud;  // etc -> falta algo para que sea útil


Quisiera poder hacer algo parecido a lo anterior pero con una instancia de clase por ejemplo (pero no necesariamente) donde pueda hacer que el setter chequee si el valor es positivo y sino arroje una excepcion pero que internamente sea un entero y por tanto me habilite a: operaciones sin casting entre enteros y enteros-sin-signo (entre ellas las comparaciones)

A groso modo...... muy grosero claro..... quiero implementar con algo de azucar sintactica esto:

Código
  1. #include <stdio.h>
  2.  
  3. class Natural
  4. {
  5. private:
  6. int valor;
  7.  
  8. public:
  9. void setVal(int v){
  10. if (v<0){
  11. printf("Error! %d no es un numero natural positivo! \n",v);
  12. exit(EXIT_FAILURE);
  13. }
  14.  
  15. this->valor = v;
  16. }
  17.  
  18. int getVal(){
  19. return valor;
  20. }
  21.  
  22. };
  23.  
  24. int main(){
  25. Natural n;
  26. n.setVal(10);
  27.  
  28. //if (n.getVal()==10)
  29. // someTask();
  30. }
  31.  

Quisiera poder usarlo asi:

Código
  1. Natural n1 5; // declaro 5 de tipo Natural
  2. Natural n2 -3; // aca se lanzaria excepcion o error en tiempo de compilacion (de implementarse de alguna manera que no me imagino con macros que lo dudo)
  3.  

Si pudiera la solucion servirme para C y no solo C++ genial.......  :P




Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: crack81 en 23 Abril 2016, 06:35 am
Bueno lo mas cercano a lo que tu quieres son las famosas propiedades "lenguajes" como Delphi desde hace mucho años las implementan, son variables de clase que simulan estar accediendo a un variable comun y corriente

ejemplo:

Código
  1. Clase.miVariable:=valor;

Visualmente parece una simple asignación pero internamente se estan ejecutando métodos escritura y lectura que validan el valor asignado, para muchos mejor que los famosos getters y setters clásicos pero es ya cuestión de gustos.

Si no mal recuerdo c++ nativo no posee esto las únicas veces que lo he visto algo similar han sido en c++ builder de embarcadero y visual studio de microsoft.

Te dejo unos links si te interesan.  :silbar:

Version visual studio  :-[
https://msdn.microsoft.com/en-us/library/2f1ec0b1.aspx (https://msdn.microsoft.com/en-us/library/2f1ec0b1.aspx)

Version c++ builder  ;D
http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4031/Implementing-a-Property-in-C.htm (http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4031/Implementing-a-Property-in-C.htm)


Por ultimo dale una mirada a la biblioteca cstdint para implementar de manera mas comoda los enteros con y sin signo

ejemplo:

(https://i.gyazo.com/522def6e21a149eefec329e0ebb5cb97.png)

link:http://www.cplusplus.com/reference/cstdint/ (http://www.cplusplus.com/reference/cstdint/)

Si tienes dudas avisa
Saludos...


PD: Eso que quieres implementar de:
Código
  1. Natural 5; // declaro 5 de tipo Natural
  2. Natural -3; // aca se lanzaria excepcion o error en tiempo de compilacion (de implementarse de alguna manera que no me imagino con macros que lo dudo)

Es imposible ya que Natural por fuerza es el tipo de dato por ende no puedes declarar una variable llamada 5 o -3

la implementacion correcta a la que te refieres es esta:
Código
  1. Natural value1=5;
  2. Nautral value2=-3;

y al momento de hacer la asignación valide los datos, similar a las propiedades que te mencione arriba.


Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: HardForo en 23 Abril 2016, 13:02 pm
Muchas gracias crack81, muy buena información ;D


Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: ivancea96 en 23 Abril 2016, 13:25 pm
¿Constructores y operadores?


Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: MAFUS en 23 Abril 2016, 14:03 pm
Recuerda que los números naturales empiezan en el 1, sino son enteros.

Ups, vale, que existen las dos formas: la que incluye 0 en el conjunto de los naturales y la que no incluye el 0 en el conjunto de los naturales. No he dicho nada.  :silbar:


Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: HardForo en 23 Abril 2016, 14:48 pm
ivancea96: podrás mostrarme alguna implementación de lo que busco ?  realmente llevo pocos dias con C / C++ y no estoy ni cerca de poder lograr lo que necesito, gracias

Recuerda que los números naturales empiezan en el 1, sino son enteros.

Ups, vale, que existen las dos formas: la que incluye 0 en el conjunto de los naturales y la que no incluye el 0 en el conjunto de los naturales. No he dicho nada.  :silbar:

Cierto, asi es.....   :xD


Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: ivancea96 en 23 Abril 2016, 15:17 pm
Ejemplo usando tu clase.

Código
  1. #include <iostream>
  2. #include <stdexcept>
  3.  
  4. using namespace std;
  5.  
  6.  
  7. class Natural{
  8.  
  9. int value;
  10.  
  11. public:
  12.  
  13. Natural():value(0){}
  14. Natural(int n):value(n){
  15. if(n<0)
  16. throw out_of_range("Not a natural number");
  17. }
  18.  
  19. Natural(const Natural& n):value(n.value){}
  20.  
  21. Natural& operator=(const Natural& n){
  22. value = n.value;
  23. return *this;
  24. }
  25.  
  26. Natural& operator+=(const Natural& n){
  27. value = operator+(n.value);
  28. return *this;
  29. }
  30.  
  31. Natural& operator-=(const Natural& n){
  32. value = operator-(n.value);
  33. return *this;
  34. }
  35.  
  36. Natural operator+(const Natural& n) const{
  37. int temp = value + n.value;
  38. if(temp<value)
  39. throw overflow_error("Addition overflow");
  40. return Natural(temp);
  41. }
  42.  
  43. Natural operator-(const Natural& n) const{
  44. int temp = value - n.value;
  45. if(temp<0)
  46. throw underflow_error("Subtraction underflow");
  47. return Natural(temp);
  48. }
  49.  
  50. operator int() const{
  51. return value;
  52. }
  53.  
  54. };
  55.  
  56. int main(){
  57. Natural n(5),
  58. n2 = 670;
  59. cout << (n+n2) << endl;
  60.  
  61. try{
  62. n -= 6;
  63. cout << n << endl;
  64. }catch(exception& exc){
  65. cout << "Exception: " << exc.what() << endl;
  66. }
  67. }


Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: HardForo en 23 Abril 2016, 18:33 pm
Te agradezco el esfuerzo, sin embargo no se comporta como debería:

Código
  1. Natural n(5),
  2. n2 = -670;
  3. cout << (n+n2) << endl; // 675
  4.  

5-670 no es +675


Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: ivancea96 en 23 Abril 2016, 22:59 pm
De hecho, no llega a hacer el cout, porque tira excepción. No puedes asignarle un número negativo a un Natural. Mira el constructor.


Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: HardForo en 23 Abril 2016, 23:48 pm
Te juro que me dio el resultado que te digo porque de hecho hasta lo pastié pero ahora volví a compilar y me dio std::out_of_range

Sin embargo, el requerimiento es poder hacer operaciones entre un "entero sin signo" (implementado como sea) y un entero.

Asi como está.... no permite la operación y no me sirve.


Título: Re: Forma segura de implementar tipo Naturales positivos
Publicado por: ivancea96 en 24 Abril 2016, 00:07 am
Sin duda, no iba a implementar todos los operadores. Impleméntalos si los necesitas. Haz operadores que acepten int, por ejemplo.