Autor Tema: Por que el siguiente codigo no sigue con la logica esperada  (Leído 5394 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Por que el siguiente codigo no sigue con la logica esperada
« en: 11 de Junio de 2013, 16:29:11 »
Hola, el siguiente código es un ejemplo muy sencillo de clases en C++, sucede algo muy extraño

Me explico:

Hay una función que asigna dos argumentos var_base y var_altura pero primero pide los datos del 2do argumento, por que sucede esto? debería pedir primero el primer argumento, luego el segundo y no al revés, siguiendo la secuencia de los parámetros primero Base y Luego Altura

ver:
Código: C++
  1. void objeto_rectangulo::cargar_lados( float var_base, float var_altura )

Código: C++
  1. //Inicio del Codigo
  2. #include<iostream>
  3. using namespace std;
  4.  
  5. class tipo_objeto_cuadrado;   // Declaración de la clase tipo_objeto_cuadrado
  6. class tipo_objeto_rectangulo; // Declaración de la clase tipo_objeto_rectangulo
  7. class tipo_objeto_triangulo; // Declaración de la clase tipo_objeto_triangulo
  8.  
  9. // I) Definicion de la clase tipo_objeto_cuadrado
  10. class tipo_objeto_cuadrado{ // forma del tipo o clase de lo que sera el objeto_cuadrado
  11.         // Funcion de amistad entre clases
  12.         friend bool comparar_figuras( tipo_objeto_cuadrado &ref_objeto_cuadrado, tipo_objeto_rectangulo &ref_objeto_rectangulo );
  13.        
  14.         private: // esta sentencia se puede suprimir
  15.                 //Variables:
  16.                 //Declaracion:
  17.                 float base, area; // Como Numérico Real
  18.         // Fin de privado
  19.                
  20.         public:
  21.                 //Procedimientos:
  22.                
  23.                 // Declaración y Definición de un procedimiento interno ( procedimiento = metodo o funcion )
  24.                 void cargar_base( float arg_base ){ // fija o asigna un valor a la variable privada base
  25.                         //Inicio del Procedimiento     
  26.                         //Parámetros( arg_base Como Tipo Numérico Real )
  27.                         //Salida() // ninguna
  28.                        
  29.                         //Algoritmo:
  30.                         //Definicion:
  31.                         base = arg_base; // Asignacion de la variable privada base
  32.                         //Fin del Procedimiento
  33.                 }
  34.                
  35.                 // Declaración y Definición de un procedimiento interno
  36.                 float introducir_base_por_teclado( void ){
  37.                         //Inicio del Procedimiento     
  38.                         //Parametros() // ninguno
  39.                         //Salida( valor_entrada Como Numérico Real )
  40.                        
  41.                         //Variables:
  42.                         float valor_entrada;
  43.                        
  44.                         //Algoritmo:
  45.                         cout << "Base = "; // mensaje de salida
  46.                         cin >> valor_entrada; // captura del dato por teclado
  47.                         return valor_entrada; // retorno hacia la salida del procedimiento
  48.                         //Fin del Procedimiento
  49.                 }
  50.                
  51.                 void cargar_lados( float arg_base, float arg_altura );
  52.                
  53.                 // Declaración y Definición de un procedimiento interno
  54.                 float leer_base( void ){ // sobrecarga de operadores de clases diferentes, leer_base tambien se define para el objeto rectangulo
  55.                         //Inicio del Procedimiento     
  56.                         //Parametros() // ninguno
  57.                         //Salida( base Como Numérico Real )
  58.                        
  59.                         return base; // retorno hacia la salida del procedimiento
  60.                         //Fin del Procedimiento
  61.                 }      
  62.                
  63.                 void calcular_area( void ){
  64.                         area = base * base;
  65.                 }
  66.                
  67.                 // Declaración y Definición de un procedimiento interno
  68.                 float leer_area( void ){ // sobrecarga de operadores de clases diferentes, leer_area tambien se define para el objeto rectangulo
  69.                         //Inicio del Procedimiento     
  70.                         //Parametros() // ninguno
  71.                         //Salida( area Como Numérico Real )
  72.                        
  73.                         return area; // retorno hacia la salida del procedimiento
  74.                         //Fin del Procedimiento
  75.                 }      
  76.                
  77.                 void imprimir_datos( void ){ // sobrecarga de operadores de clases diferentes, imprimir_datos tambien se define para el objeto rectangulo
  78.                         cout << "\nCuadrado:" << endl;
  79.                         cout << "\nBase del Cuadrado= " << leer_base() << endl; // mensaje de salida
  80.                         cout << "Area del Cuadrado= " << leer_area() << endl << endl; // mensaje de salida
  81.                 }              
  82.                
  83.         // Fin de public       
  84. };     
  85.  
  86. // II) Definicion de la clase tipo_objeto_rectangulo
  87. class tipo_objeto_rectangulo{
  88.         // Funcion de amistad entre clases
  89.         friend bool comparar_figuras( tipo_objeto_cuadrado &ref_objeto_cuadrado, tipo_objeto_rectangulo &ref_objeto_rectangulo );
  90.        
  91.         private:
  92.                 //Variables:
  93.                 float base, altura, area; // Como Numérico Real
  94.         // Fin de privado
  95.                
  96.         public:
  97.                 //Procedimientos:
  98.                 // Declaración de un procedimiento externo  
  99.                
  100.                 void cargar_base( float arg_base ); // sobrecarga de procedimiento en diferentes clases
  101.                 void cargar_altura( float arg_base );
  102.                 void cargar_lados( float arg_base, float arg_altura );  
  103.                
  104.                 void cargar_lados_del_objeto( float arg_lado );  // sobrecarga de procedimiento en la misma clase
  105.                 void cargar_lados_del_objeto( float arg_lado1, float arg_lado2 );  
  106.                                
  107.                 // Declaración y Definición de un procedimiento interno
  108.                 float introducir_base_por_teclado( void ){  
  109.                         //Inicio del Procedimiento     
  110.                         //Parametros(  ) // ninguno
  111.                         //Salida( valor_entrada Como Numérico Real )
  112.                        
  113.                         //Variables:
  114.                         float valor_entrada;
  115.                        
  116.                         // Algoritmo:
  117.                         cout << "Base = "; // mensaje de salida en pantalla para introducion de datos
  118.                         cin >> valor_entrada; // captura del dato por teclado
  119.                         return valor_entrada; // retorno hacia la salida del procedimiento
  120.                         //Fin del Procedimiento
  121.                 }
  122.                
  123.                 // Declaración y Definición de un procedimiento interno
  124.                 float introducir_altura_por_teclado( void ){  
  125.                         //Inicio del Procedimiento     
  126.                         //Parametros() // ninguno
  127.                         //Salida( valor_entrada Como Numérico Real )
  128.                        
  129.                         //Variables:
  130.                         float valor_entrada;
  131.                        
  132.                         // Algoritmo:
  133.                         cout << "Altura = "; // mensaje de salida en pantalla para introducion de datos
  134.                         cin >> valor_entrada; // captura del dato por teclado
  135.                         return valor_entrada; // retorno hacia la salida del procedimiento
  136.                         //Fin del Procedimiento
  137.                 }
  138.                
  139.                 // Declaración y Definición de un procedimiento interno
  140.                 float leer_base( void ){  // sobrecarga de operadores de clases diferentes, leer_base tambien se define para el objeto rectangulo
  141.                         //Inicio del Procedimiento     
  142.                         //Parametros() // ninguno
  143.                         //Salida( base Como Numérico Real )
  144.                        
  145.                         return base; // retorno hacia la salida del procedimiento
  146.                         //Fin del Procedimiento
  147.                 }      
  148.                
  149.                
  150.                 // Declaración y Definición de un procedimiento interno
  151.                 float leer_altura( void ){
  152.                         //Inicio del Procedimiento     
  153.                         //Parametros() // ninguno
  154.                         //Salida( altura Como Numérico Real )
  155.                        
  156.                         return altura; // retorno hacia la salida del procedimiento
  157.                         //Fin del Procedimiento
  158.                 }      
  159.                
  160.                 void calcular_area( void ){
  161.                         area = base * altura;
  162.                 }
  163.                
  164.                 // Declaración y Definición de un procedimiento interno
  165.                 float leer_area( void ){ // sobrecarga de operadores de clases diferentes, leer_area tambien se define para el objeto rectangulo
  166.                         //Inicio del Procedimiento     
  167.                         //Parametros() // ninguno
  168.                         //Salida( area Como Numérico Real )
  169.                        
  170.                         return area; // retorno hacia la salida del procedimiento
  171.                                 //Fin del Procedimiento
  172.                 }
  173.                
  174.                 void imprimir_datos( void ){ // sobrecarga de operadores de clases diferentes, imprimir_datos tambien se define para el objeto cuadrado
  175.                         cout << "\nRectangulo:" << endl;
  176.                         cout << "\nBase del Rectangulo = " << leer_base()   << endl; // mensaje de salida
  177.                         cout << "Altura del Rectangulo = " << leer_altura() << endl; // mensaje de salida  
  178.                         cout << "Area del Rectangulo = "   << leer_area()   << endl << endl; // mensaje de salida
  179.                 }
  180.                
  181.  
  182.                
  183.         // Fin de public
  184. };             
  185.  
  186.  
  187.  
  188.  
  189. // Definición de un procedimiento externo a la clase tipo_objeto_rectangulo  
  190. void tipo_objeto_rectangulo::cargar_lados( float arg_base, float arg_altura ){  // fija o asigna valores a la variable base y altura
  191.         //Inicio del Procedimiento     
  192.         //Parametros( arg_base como Numerico Real, arg_altura como Numerico Real )
  193.         //Salida() // ninguna
  194.  
  195.         //Algoritmo:
  196.         base = arg_base; // Asignacion de la variable privada base
  197.         altura = arg_altura; // Asignacion de la variable privada altura
  198.         //Fin del Procedimiento
  199. }
  200.  
  201.        
  202. // Definición de un procedimiento externo a la clase tipo_objeto_rectangulo  
  203. void tipo_objeto_rectangulo::cargar_base( float arg_base ){  // fija o asigna un valor a la variable privada base
  204.         //Inicio del Procedimiento     
  205.         //Parametros( arg_base Como Numerico Real )
  206.         //Salida() // ninguna
  207.        
  208.         //Algoritmo:
  209.         base = arg_base; // Asignacion de la variable privada base
  210.         //Fin del Procedimiento
  211. }
  212.        
  213.          
  214.        
  215. // Definición de un procedimiento externo a la clase tipo_objeto_rectangulo
  216. void tipo_objeto_rectangulo::cargar_altura( float arg_altura ){ // fija o asigna un valor a la variable privada altura
  217.         //Inicio del Procedimiento     
  218.         //Parámetros( arg_base Como Tipo Numérico Real )
  219.         //Salida() // ninguna
  220.        
  221.         //Algoritmo:
  222.         altura = arg_altura; // Asignacion de la variable privada altura
  223.         //Fin del Procedimiento
  224. }      
  225.  
  226. // Definición de un procedimiento externo a la clase tipo_objeto_rectangulo  
  227. void tipo_objeto_rectangulo::cargar_lados_del_objeto( float arg_lado0 ){  // fija o asigna un valor a la variable privada base con un solo argumento
  228.         //Inicio del Procedimiento     
  229.         //Parametros( arg_lado Como Numerico Real )
  230.         //Salida() // ninguna
  231.        
  232.         //Algoritmo:
  233.         base = arg_lado0; // Asignacion de la variable privada base
  234.         //Fin del Procedimiento
  235. }
  236.  
  237. // Definición de un procedimiento externo a la clase tipo_objeto_rectangulo  
  238. void tipo_objeto_rectangulo::cargar_lados_del_objeto( float arg_lado0, float arg_lado1 ){  // fija o asigna un valor a la variable privada base con un solo argumento
  239.         //Inicio del Procedimiento     
  240.         //Parametros( arg_lado Como Numerico Real )
  241.         //Salida() // ninguna
  242.        
  243.         //Algoritmo:
  244.         base = arg_lado0; // Asignacion de la variable privada base
  245.         altura = arg_lado1; // Asignacion de la variable privada altura
  246.         //Fin del Procedimiento
  247. }
  248.  
  249.  
  250. bool comparar_figuras( tipo_objeto_cuadrado &ref_objeto_cuadrado, tipo_objeto_rectangulo &ref_objeto_rectangulo ){ // Definición del procedimiento amigo  
  251.         //Inicio del Procedimiento Como Amigo
  252.        
  253.         //Parametros( figura_cuadrado Como Referencia, figura_rectangulo Como Referencia )
  254.         //Salida( bandera Como Boole )
  255.        
  256.         //Variables:
  257.         bool bandera_comparacion;
  258.        
  259.         //float  a;
  260.        
  261.         //a = ref_objeto_cuadrado.leer_base();
  262.        
  263.         //Algoritmo:
  264. //      if( ref_objeto_cuadrado.base == ref_objeto_rectangulo.base ||
  265. //              ref_objeto_cuadrado.base == ref_objeto_rectangulo.altura )
  266.        
  267.         // Mejor usar la funcion leer_base() en lugar del identificador
  268.         if( ref_objeto_cuadrado.leer_base() == ref_objeto_rectangulo.leer_base() ||
  269.             ref_objeto_cuadrado.leer_base() == ref_objeto_rectangulo.leer_altura() )   
  270.         {
  271.                 bandera_comparacion = true;
  272.         }else{
  273.                 bandera_comparacion = false;
  274.         }
  275.        
  276.         return bandera_comparacion;
  277.  
  278.         //Fin del Procedimiento
  279. }
  280.  
  281.  
  282. class tipo_objeto_triangulo: public
  283.         // Herencia
  284.         tipo_objeto_rectangulo{
  285.                 // Funcion de amistad entre clases
  286.                 friend bool comparar_figuras( tipo_objeto_cuadrado &ref_objeto_cuadrado, tipo_objeto_rectangulo &ref_objeto_rectangulo );
  287.                
  288.         private:
  289.                 //Variables:
  290.                 // float base, altura; // Como Numérico Real // vars heredadas
  291.                 float lado2, lado3; // nuevas variables
  292.                 // Fin de privado
  293.                
  294.         public:
  295.                 //Procedimientos:
  296.                
  297.                 // Declaración y Definición de un procedimiento interno
  298.                 void cargar_lado2( float arg_lado2 ){ // fija o asigna un valor a la variable privada lado2
  299.                         //Inicio del Procedimiento     
  300.                         //Parámetros( arg_lado2 Como Tipo Numérico Real )
  301.                         //Salida() // ninguna
  302.                        
  303.                         //Algoritmo:
  304.                         //Definicion:
  305.                         lado2 = arg_lado2; // Asignacion de la variable privada lado2
  306.                         //Fin del Procedimiento
  307.                 }
  308.                
  309.                 // Declaración y Definición de un procedimiento interno
  310.                 void cargar_lado3( float arg_lado3 ){ // fija o asigna un valor a la variable privada lado3
  311.                         //Inicio del Procedimiento     
  312.                         //Parámetros( arg_lado2 Como Tipo Numérico Real )
  313.                         //Salida() // ninguna
  314.                        
  315.                         //Algoritmo:
  316.                         //Definicion:
  317.                         lado3 = arg_lado3; // Asignacion de la variable privada lado2
  318.                         //Fin del Procedimiento
  319.                 }              
  320.                
  321.                 // Declaración y Definición de un procedimiento interno
  322.                 float introducir_lado2_por_teclado( void ){
  323.                         //Inicio del Procedimiento     
  324.                         //Parametros() // ninguno
  325.                         //Salida( valor_entrada Como Numérico Real )
  326.                        
  327.                         //Variables:
  328.                         float valor_entrada;
  329.                        
  330.                         //Algoritmo:
  331.                         cout << "2do lado = "; // mensaje de salida
  332.                         cin >> valor_entrada; // captura del dato por teclado
  333.                         return valor_entrada; // retorno hacia la salida del procedimiento
  334.                         //Fin del Procedimiento
  335.                 }
  336.                
  337.                 float introducir_lado3_por_teclado( void ){
  338.                         //Inicio del Procedimiento     
  339.                         //Parametros() // ninguno
  340.                         //Salida( valor_entrada Como Numérico Real )
  341.                        
  342.                         //Variables:
  343.                         float valor_entrada;
  344.                        
  345.                         //Algoritmo:
  346.                         cout << "3cer lado = "; // mensaje de salida
  347.                         cin >> valor_entrada; // captura del dato por teclado
  348.                         return valor_entrada; // retorno hacia la salida del procedimiento
  349.                         //Fin del Procedimiento
  350.                 }      
  351.                
  352.                 // Declaración y Definición de un procedimiento interno
  353.                 float leer_lado2( void ){
  354.                         //Inicio del Procedimiento     
  355.                         //Parametros() // ninguno
  356.                         //Salida( lado2 Como Numérico Real )
  357.                        
  358.                         return lado2; // retorno hacia la salida del procedimiento
  359.                         //Fin del Procedimiento
  360.                 }                      
  361.                
  362.                 // Declaración y Definición de un procedimiento interno
  363.                 float leer_lado3( void ){
  364.                         //Inicio del Procedimiento     
  365.                         //Parametros() // ninguno
  366.                         //Salida( lado3 Como Numérico Real )
  367.                        
  368.                         return lado3; // retorno hacia la salida del procedimiento
  369.                         //Fin del Procedimiento
  370.                 }      
  371.                
  372.                 float calcular_area( void ){ // Se redefine el metodo o funcion calcular_area del objeto rectangulo, la funcion base se oculta
  373.                         //area = base * base; // Codigo original
  374.                         //area = ( base * altura ) / 2; // Codigo buscado
  375.                         float temp;
  376.                         temp = ( leer_base() * leer_altura() ) / 2 ;
  377.                        
  378.                         return temp;
  379.                 }
  380.                
  381.                 void imprimir_datos( void ){ // sobrecarga de operadores de clases diferentes, imprimir_datos tambien se define para el objeto cuadrado, y rectangulo
  382.                         cout << "\nTriangulo:" << endl;
  383.                         cout << "Base del Triangulo = " << leer_base() << endl; // mensaje de salida
  384.                         cout << "Altura del Triangulo = " << leer_altura() << endl; // mensaje de salida  
  385.                         cout << "2do lado del Triangulo = " << leer_lado2() << endl; // mensaje de salida
  386.                         cout << "3cer lado del Triangulo = " << leer_lado3() << endl; // mensaje de salida
  387.                        
  388.                         //cout << "Area del Triangulo = " << leer_area() << endl << endl; // mensaje de salida
  389.                         cout << "Area del Triangulo = " << calcular_area() << endl << endl; // mensaje de salida
  390.                        
  391.                        
  392.                 }
  393.                
  394.        
  395.                
  396.                 // Fin de public
  397.         };     
  398. // Fin tipo_objeto_triangulo
  399.  
  400.  
  401. int main ( int argc, char *argv[] ) {
  402.         //Inicio del Procedimiento principal
  403.         //Parámetros( int argc, char *argv[] )
  404.         //Salida() // ninguna
  405.        
  406.         //Variables:
  407.         bool bandera1;
  408.        
  409.         //Algoritmo:
  410.         tipo_objeto_cuadrado figura_cuadrado;     // figura_cuadrado Como Tipo de tipo_objeto_cuadrado
  411.         tipo_objeto_rectangulo figura_rectangulo; // figura_rectangulo Como Tipo de tipo_objeto_rectangulo
  412.         tipo_objeto_triangulo figura_triangulo;   // figura_triangulo Como Tipo de tipo_objeto_triangulo
  413.        
  414.         // Cuadrado
  415.         cout << "Entre valor de la base del cuadrado" << endl;
  416.        
  417.         figura_cuadrado.cargar_base( figura_cuadrado.introducir_base_por_teclado() ); // Cargar_base( introducir_base_por_teclado de figura_cuadrado ) en figura_cuadrado  
  418.         figura_cuadrado.calcular_area();
  419.        
  420.         // Rectangulo
  421.         //cout << "Entre valor de la base del cuadrado" << endl;
  422.         //figura_rectangulo.cargar_base( figura_rectangulo.introducir_base_por_teclado() );     // Cargar_base( introducir_base_por_teclado de figura_cuadrado ) en figura_rectangulo
  423.        
  424.         //cout << "Entre valor de la altura del rectangulo" << endl;
  425.         //figura_rectangulo.cargar_altura( figura_rectangulo.introducir_altura_por_teclado() ); // Cargar_altura( introducir_altura_por_teclado de figura_cuadrado ) en figura_rectangulo
  426.        
  427.         // La 2 sentencias anteriores (figura_ ...) en una sola
  428.         //cout << "\nEntre valores de los lados del rectángulo Base, luego Altura" << endl;
  429.         //figura_rectangulo.cargar_lados( figura_rectangulo.introducir_base_por_teclado(), figura_rectangulo.introducir_altura_por_teclado() ); // Cargar_lados( introducir_base_por_teclado de figura_cuadrado, introducir_base_por_teclado de figura_cuadrado  ) en figura_rectangulo
  430.  
  431.     // otro forma de almacenar datos, usando la sobrecarga de metodos o funciones de una misma clase
  432.        
  433.         cout << "\n\nEntre valores de los lados del rectángulo Base, luego Altura" << endl;
  434.         //La siguiente sentencia solo introduce el lado de la base
  435.         //figura_rectangulo.cargar_lados_del_objeto( figura_rectangulo.introducir_base_por_teclado() ); // Cargar_lados( introducir_base_por_teclado de figura_cuadrado, introducir_base_por_teclado de figura_cuadrado  ) en figura_rectangulo
  436.        
  437.         //La siguiente sentencia introduce el lado de la base y altura
  438.         figura_rectangulo.cargar_lados_del_objeto( figura_rectangulo.introducir_base_por_teclado(), figura_rectangulo.introducir_altura_por_teclado() ); // Cargar_lados( introducir_base_por_teclado de figura_cuadrado, introducir_base_por_teclado de figura_cuadrado  ) en figura_rectangulo
  439.         figura_rectangulo.calcular_area();
  440.        
  441.         // Triangulo
  442.         cout << "\n\nEntre valor de la base del triangulo" << endl;
  443.         figura_triangulo.cargar_base( figura_triangulo.introducir_base_por_teclado() );
  444.        
  445.         cout << "Entre valor de la altura del triangulo" << endl;
  446.         figura_triangulo.cargar_altura( figura_triangulo.introducir_altura_por_teclado() );    
  447.        
  448.         cout << "Entre valor del 2do lado del triangulo" << endl;
  449.         figura_triangulo.cargar_lado2( figura_triangulo.introducir_lado2_por_teclado() );      
  450.        
  451.         cout << "Entre valor del 3cer lado del triangulo" << endl;
  452.         figura_triangulo.cargar_lado3( figura_triangulo.introducir_lado3_por_teclado() );
  453.         //figura_triangulo.calcular_area();
  454.        
  455.         // Impresion de datos
  456.         cout << "\n\nDatos:" << endl;
  457.         figura_cuadrado.imprimir_datos();
  458.         figura_rectangulo.imprimir_datos();
  459.         figura_triangulo.imprimir_datos();
  460.        
  461.         // Probar si tienen algun lado en comun
  462.         bandera1 = comparar_figuras( figura_cuadrado, figura_rectangulo );
  463.        
  464.         if( bandera1 ) {
  465.                 cout << "\n\nLas figuras cuadrado y rectangulo tienen un lado en común (mismo valor)"<< endl;
  466.         } else {
  467.                 cout << "\n\nLas figuras cuadrado y rectangulo NO tienen un lado en común (mismo valor)"<< endl;
  468.         }
  469.        
  470.         return 0;
  471.         //Fin del Procedimiento principal
  472. }
  473. //Fin del Codigo

^ Código actualizado Lunes 17 de junio
« Última modificación: 18 de Junio de 2013, 16:47:22 por CompSystems »
Desde Colombia

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #1 en: 11 de Junio de 2013, 18:18:52 »
Las Reglas de Programacion orientada a objetos te dicen que:
1. Nunca debes utilizar la misma funcion para leer variables diferentes. Simpre se crea una funcion de get y una de set para cada variable.
2. las funciones get y set seran publicas, mientras que las variables privadas
3. las funciones friend solamente se deben usar en casos muuuuuyyy especiales, debes evitarlas lo mas que puedas. De hecho en Java no existen.

ej:
Código: [Seleccionar]
class objeto_rectangulo{
private:
    float m_base, m_altura;
public:
    void setBase(float base){
        m_base = base;
    }
   
    void setAltura(float altura){
        m_altura = altura;
    }
   
    float base(){
        return m_base;
    }
   
    float altura(){
        return m_altura;
    }
}



Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #2 en: 12 de Junio de 2013, 09:35:14 »
Muchas Gracias BigLuis por tu respuesta, el código anterior fue portado de un Psuedo code a C++, lo que implica que no es tan "literal" pasar de pseudocode a un lenguaje especifico si el lenguaje de programacion tiene reglas que lo limitan

No conocía esta regla de la programacion orientada  a objetos en C++
Citar
1. Nunca debes utilizar la misma función para leer o asignar variables diferentes. Siempre se crea una función de get(leer) y una de set (asignar) para cada variable.


« Última modificación: 12 de Junio de 2013, 12:46:47 por CompSystems »
Desde Colombia

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #3 en: 12 de Junio de 2013, 11:52:37 »
Muchas Gracias BigLuis por tu respuesta, el código anterior fue portado de un Psuedo code a C++, lo que implica que no es tan "literal" pasar de pseudocode a un lenguaje especifico si el lenguaje de programacion tiene reglas que lo limitan


Un pseudocódigo es como un borrador. Básicamente solo sirve para tener una idea global del problema. Casi nunca se sigue al pie de la letra.

No conocía esta regla de la programacion orientada  a objetos en C++
Citar
1. Nunca debes utilizar la misma función para leer o asignar variables diferentes. Siempre se crea una función de get(leer) y una de set (asignar) para cada variable.
(sucede lo mismo en JAVA? u otros lenguajes orientados a objetos?)

Lo que tu hiceste fue usar la funcion cargar_lado(float lado) para base y para altura. Ciertamente la funcion cargar_lados() la pudiste haber reescrito de otra manera:

Código: [Seleccionar]
void rectangulo::cargar_lados(float base,float altura){
  m_base = base;
  m_altura = altura;
}


// Para que el código anterior trabaje correctamente la siguiente función:
// La función void cargar_lados( float var_base, float var_altura )
Código: C++
  1. void cargar_lados( float var_base, float var_altura );  // C++ no puede con esto =(

se derivo en dos funciones independientes, pero me parece que debería trabajar la definición anterior, Por que el compilador o lenguaje no es capaz con ello??  :shock:, esto implica crear una función de un solo argumento para cada cosa, o hay otra manera mas sofisticada de hacer asignacion en el código de arriba?  :2]

Código: C++
  1. void cargar_base( float var_base );            
  2. void cargar_altura( float var_base );
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #4 en: 12 de Junio de 2013, 12:07:24 »
Descubrí el problema:

El compilador de C++ evalúa los argumentos de una función en un orden NO secuencial (aunque no debería ser así), por esta razón imaginaba que la respuesta seria tambien secuencial,  pues en otros lenguajes que he programado, siempre se pide cada uno de los argumentos en el orden en que fueron definidos dentro de la funcion

En C++
f1( arg0, arg1, argn )

Suponiendo que arg0 modifica una variable var0 y la pide por teclado,  y arg1 modifica una variable var1 y la pide tambien por teclado, ... y asi sucesivamente, entonces es de esperarse que en consola se pida introducir el dato para primer argumento arg0, pero NO ES ASÍ /!\, y como yo NO estaba etiquetando la entrada de datos, supuse que el primer argumento a introducir era para el primer argumento de la función y así sucesivamente ...,

Si ejecutan el código del 1er post, observaran que primero les pide la altura y luego la base (C++ por que trabajáis así) :5] , pero yo lo había definido primero leer la base y luego la altura  

Código: C++
  1. figura_rectangulo.cargar_lados( figura_rectangulo.leer_base_por_teclado(), figura_rectangulo.leer_altura_por_teclado() );
« Última modificación: 12 de Junio de 2013, 13:23:12 por CompSystems »
Desde Colombia

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #5 en: 12 de Junio de 2013, 12:53:53 »
Y has probado de esta manera:

Código: [Seleccionar]
class objeto_rectangulo{
private:
    float m_base, m_altura;
public:
    void setBase(float base){
        m_base = base;
    }
   
    void setAltura(float altura){
        m_altura = altura;
    }
   
    float base(){
        return m_base;
    }
   
    float altura(){
        return m_altura;
    }

    void rectangulo::cargar_lados(float base,float altura){
        m_base = base;
        m_altura = altura;
    }
}

main(){
  float base,altura;
  objeto_rectangulo rectangulo;
  cout<<"base: ";
  cin>>base;
  cout<<"altura: ";
  cin>>altura;
  rectangulo.cargar_lados(base,altura);
 
}
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #6 en: 12 de Junio de 2013, 13:59:57 »
gracias nuevamente, tu código llamando los parámetros de rectangulo.cargar_lados(base,altura); con dos funciones, podran ver que primero pide los datos de la altura luego la base, no sigue el orden lógico de los parámetros de la función

Código: C++
  1. #include<iostream>
  2. using namespace std;
  3.  
  4.  
  5.  
  6. class objeto_rectangulo{
  7. private:
  8.         float m_base, m_altura;
  9. public:
  10.         void setBase(float base){
  11.                 m_base = base;
  12.         }
  13.        
  14.         void setAltura(float altura){
  15.                 m_altura = altura;
  16.         }
  17.        
  18.         float base(){
  19.                 return m_base;
  20.         }
  21.        
  22.         float altura(){
  23.                 return m_altura;
  24.         }
  25.        
  26.         void cargar_lados( float base,float altura ){
  27.                 m_base = base;
  28.                 m_altura = altura;
  29.         }
  30.        
  31.         void desplegar_lados( ){
  32.                 cout << "base = " << m_base << endl;
  33.                 cout << "altura = " << m_altura << endl << endl;
  34.         }
  35.        
  36.         float leer_base( ){
  37.                 float base;
  38.                 cout << "base = ";
  39.                 cin >> base;
  40.                 return base;
  41.         }
  42.        
  43.         float leer_altura( ){
  44.                 float altura;
  45.                 cout << "altura = ";
  46.                 cin >> altura;
  47.                 return altura;
  48.         }
  49.        
  50. };
  51.  
  52. int main (int argc, char *argv[]) {
  53. //      float base,altura;
  54.         objeto_rectangulo rectangulo;
  55. //      cout<<"base = ";
  56. //      cin>>base;
  57. //      cout<<"altura = ";
  58. //      cin>>altura;
  59. //      rectangulo.cargar_lados(base,altura);
  60.        
  61.         cout << "\nEntre valores de los lados del rectángulo Base, luego Altura\n" << endl;
  62.         rectangulo.cargar_lados( rectangulo.leer_base( ), rectangulo.leer_altura( ) );
  63.        
  64.         rectangulo.desplegar_lados( );
  65.         return 0;
  66.        
  67. }
Desde Colombia

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #7 en: 12 de Junio de 2013, 14:27:19 »
la manera que te mostre sigue el orden correcto?
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #8 en: 13 de Junio de 2013, 16:05:49 »
Si, por que base y altura se asignaron antes de la sentencia

rectangulo.cargar_lados(base,altura);


Bueno, pero mi ejemplo es utilizando la ventana terminal, los programas reales usan GUI

Me dijeron que el compilador optimiza el código, y "según el" primero hay que pedir los datos del 2do argumento, el compilador hace que el código sea mas eficiente, no intuitivo

Desde Colombia

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #9 en: 15 de Junio de 2013, 12:24:52 »
A eso queria llegar

Queria que te dieras cuenta que las funciones tiene un funcionamiento un poco extraño con respecto a sus argumentos. Si no me equivoco lo que ocurre es que estas funciona de una manera LIFO, Last In First Out. Lo que significa que el último cin ejecutado dentro de la misma linea es el que obtendrá los valores primero. Esto se debe a la capacidad multitasking o multithreading del computador.

« Última modificación: 15 de Junio de 2013, 12:33:51 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #10 en: 17 de Junio de 2013, 22:49:49 »
Hola BigLuis 2 preguntas

1:
Citar
3. las funciones friend solamente se deben usar en casos muuuuuyyy especiales, debes evitarlas lo mas que puedas. De hecho en Java no existen.

Cual es la causa o efecto de usar funciones de amistad?

2: En mi proceso de aprendizaje de C++ voy en herencias de clases

Incorpore al código de arriba un clase triangulo que hereda la clase rectángulo ( base, altura ),

En la clase rectángulo, el área es base * altura, pero en la clase triangulo es diferente.

esto es lo que tengo

float calcular_area( void ){ // Se redefine el metodo o funcion calcular_area del objeto rectangulo, la funcion base se oculta
         //area = base * base; // Codigo original
         //area = ( base * altura ) / 2; // Codigo buscado
         float temp;
         area = ( leer_base() * leer_altura() ) / 2 ;
         
         return temp;
      }


pero deseo

void calcular_area( void ){ // Se redefine el metodo o funcion calcular_area del objeto rectangulo, la funcion base se oculta
         //area = base * base; // Codigo original
         //area = ( base * altura ) / 2; // Codigo buscado

         area = ( leer_base() * leer_altura() ) / 2 ;
}
   
area en la clase base es privada, que puedo hacer para sobreescribirla?   
« Última modificación: 18 de Junio de 2013, 16:51:00 por CompSystems »
Desde Colombia

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Por que el siguiente codigo no sigue con la logica esperada
« Respuesta #11 en: 22 de Junio de 2013, 15:04:25 »
1. Si no me equivoco una funcion Friend es casi una funcion global, es decir mas de 2 clases no pueden tener la misma funcion friend. En otras palabras este tipo de funciones fueron hechas para romper las reglas de OOP. Este tipo de funciones no pueden ser sobreescritas. En lenguajes como Java este tipo de funciones no existen. Exactamente no entiendo porque, pero me han dicho que este tipo de funciones puede crear problemas de seguridad, por otro lado tambien es muy dificil mantener o corregir un codigo que contiene mucho de estas clases

2. La solucion es declarar esas funciones como public, lo que significa que pueden ser modificadas y utilizadas por todos. Por otro lado base y altura deben ser declaradas como protected, esto significa que esas variables pueden ser utilizadas por la clase misma y sus descendientes pero no por externos.
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA


 

anything