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.
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:
#include <stdio.h>
class Natural
{
private:
int valor;
public:
void setVal(int v){
if (v<0){
printf("Error! %d no es un numero natural positivo! \n",v);
exit(EXIT_FAILURE);
}
this->valor = v;
}
int getVal(){
return valor;
}
};
int main(){
Natural n;
n.setVal(10);
//if (n.getVal()==10)
// someTask();
}
Quisiera poder usarlo asi:
Natural n1 5; // declaro 5 de tipo Natural
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)
Si pudiera la solucion servirme para C y no solo C++ genial....... :P
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:
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:
Natural 5; // declaro 5 de tipo Natural
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:
Natural value1=5;
Nautral value2=-3;
y al momento de hacer la asignación valide los datos, similar a las propiedades que te mencione arriba.
Muchas gracias crack81, muy buena información ;D
¿Constructores y operadores?
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:
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
Cita de: 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:
Cierto, asi es..... :xD
Ejemplo usando tu clase.
#include <iostream>
#include <stdexcept>
using namespace std;
class Natural{
int value;
public:
Natural():value(0){}
Natural(int n):value(n){
if(n<0)
throw out_of_range("Not a natural number");
}
Natural(const Natural& n):value(n.value){}
Natural& operator=(const Natural& n){
value = n.value;
return *this;
}
Natural& operator+=(const Natural& n){
value = operator+(n.value);
return *this;
}
Natural& operator-=(const Natural& n){
value = operator-(n.value);
return *this;
}
Natural operator+(const Natural& n) const{
int temp = value + n.value;
if(temp<value)
throw overflow_error("Addition overflow");
return Natural(temp);
}
Natural operator-(const Natural& n) const{
int temp = value - n.value;
if(temp<0)
throw underflow_error("Subtraction underflow");
return Natural(temp);
}
operator int() const{
return value;
}
};
int main(){
Natural n(5),
n2 = 670;
cout << (n+n2) << endl;
try{
n -= 6;
cout << n << endl;
}catch(exception& exc){
cout << "Exception: " << exc.what() << endl;
}
}
Te agradezco el esfuerzo, sin embargo no se comporta como debería:
Natural n(5),
n2 = -670;
cout << (n+n2) << endl; // 675
5-670 no es +675
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.
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.
Sin duda, no iba a implementar todos los operadores. Impleméntalos si los necesitas. Haz operadores que acepten int, por ejemplo.