Ayuda con errores programa c++.

Iniciado por xboxone007, 2 Febrero 2014, 20:00 PM

0 Miembros y 3 Visitantes están viendo este tema.

xboxone007

Hola a todos,
miren estoy haciendo este ejercicio y tengo unos errores que no se como puedo solucionarlos. Esperaba que me pudieseis ayudar.
El ejercicio esta dividido en dos partes, la primera la tengo echa y funcionando pero la segunda me esta costando mucho mas.

Aquí os dejo las diferentes partes del ejercicio.

Enunciado:

Escribe una clase Vehículo con los siguientes atributos (privados):
• año: año de fabricación. Entero
• CapDepo: Capacidad del deposito en litros. Entero
• LitrosDepo: Litros en el deposito. Tiene que ser menor que CapDepo. Entero
• Kph: Km/h del vehiculo. Entero
• Propietario: cadena de caracteres de 25 posiciones
Y los siguientes métodos públicos:
• Imprimir ()
• LlenarDeposito (int nLitros)
• Todas las funciones necesarias para acceder al valor de los atributos y
modificarlos.
Además has de crear tres constructores: uno por defecto, otro con parámetros y otro de
copia.
Por ultimo crea un procedimiento principal donde

Crea dos clases derivadas de Vehículo que serán Coche y Moto. El coche tendrá como
atributos propios
• NumAsientos: numero de asientos. Entero
• Marca: marca del coche. Cadena de caracteres de 10 posiciones.
La moto tendrá como atributos propios:
• Cilindrada: Entero
• Tipo : cadena de caracteres de 20 posiciones que indicia le tipo de moto (trial,
cross, custom...)
En ambas clases crea los métodos que permitan acceder a los atributos privados y
solapa la función imprimir para que muestre la información propia aparte de la
general.

He logrado hacer diferentes archivos de encabezado ".h"y otros tanto     ".cpp" pero me corren exactamente 6 errores. Aquí os dejo el código por partes:

Primer los cuatro ".cpp":

Moto.cpp

#include "Moto.h"
#include <iostream>

using namespace std;

void Moto::Imprimir()
{
   cout << "Cilindrada de la Moto: " << cilindrada() << endl;
   cout << "Tipo de Moto: " << tipo() << endl;
}


Coche.cpp

#include "Coche.h"
#include <iostream>

using namespace std;

void Coche::Imprimir()
{
   cout << "Numero de asientos: " << this -> marca() << endl;
   cout << "Marca del Coche: " << this -> asientos() << endl;
}


Vehiculo.cpp

#include "Vehiculo.h"
#include <iostream>

using namespace std;

void Vehiculo::Imprimir()
{
   cout << "Propietario: " << this->GetPropietario() << endl;
   cout << "año de fabricacion: " << this->GetAño() << endl;
   cout << "Capacidad del deposito: " << this->GetCapDepo() << " Litros. ";
   cout << this->GetLitrosDepo() << " Litros actualmente" << endl;
   cout << "Velocidad maxima: " << this->GetKph() << " Km/h" << endl;
}

int Vehiculo::LlenarDeposito(int litros)
{
   this->SetLitrosDepo(this->GetLitrosDepo() + litros);
   return this->GetLitrosDepo();
}


Source.cpp

#include <iostream>
#include <iomanip>
#include "Vehiculo.h"

using namespace std;

int main(){

   Vehiculo vehiculoA;
   cout << "VEHICULO A - Constructor por defecto" << endl;
   vehiculoA.Imprimir();
   cout << "-------------------------------" << endl;
   cout << endl;

   cout << "VEHICULO A - SetPropietario(\"Bruce Willis\")" << endl;
   vehiculoA.SetPropietario("Bruce Willis");
   vehiculoA.Imprimir();
   cout << "-------------------------------" << endl;
   cout << endl;

   cout << "VEHICULO A - LlenarDeposito(50)" << endl;
   vehiculoA.LlenarDeposito(50);
   vehiculoA.Imprimir();
   cout << "-------------------------------" << endl;
   cout << endl;
   
   cout << "VEHICULO A - LlenarDeposito(500)" << endl;
   vehiculoA.LlenarDeposito(500);
   vehiculoA.Imprimir();
   cout << "-------------------------------" << endl;
   cout << endl;

   cout << "_____________________________________________________________________" << endl;

   Vehiculo vehiculoB(1987, 55, 180);
   cout << "VEHICULO B - Constructor(1987, 55, 180)" << endl;
   vehiculoB.Imprimir();
   cout << "-------------------------------" << endl;
   cout << endl;

   cout << "VEHICULO B - SetPropietario(\"Jennifer Aniston\")" << endl;
   vehiculoB.SetPropietario("Jennifer Aniston");
   vehiculoB.Imprimir();
   cout << "-------------------------------" << endl;
   cout << endl;

   cout << "_____________________________________________________________________" << endl;

   Vehiculo vehiculoC(vehiculoB);
   cout << "VEHICULO C - Constructor copia(Vehiculo B)" << endl;
   vehiculoC.Imprimir();
   cout << "-------------------------------" << endl;
   cout << endl;

   cout << endl << endl;
   system("Pause");
}


Ahora pondré los ".h"que son tres:

Moto.h

#include <string>

class Moto{

private:
     char* tipo;
     int cilindrada;

public:
     void Imprimir();
     void Settipo(char*);
     char* Gettipo();
}


Coche.h

[COLOR="teal"]#include <string>

class Coche{

private:
     char* marca;
    int asientos;

public:
     void Imprimir();
     void SetMarca(char*);
     char* GetMarca();
}[/color]

Vehiculo.h

#include <string>

class Vehiculo{

private:
   int año;
   int capDepo;
   int litrosDepo;
   int kph;
   char propietario[25];

public:
   Vehiculo(){
      SetAño(2000);
      SetCapDepo(100);
      SetLitrosDepo(0);
      SetKph(300);
      SetPropietario("");
   }

   Vehiculo(int _año, int _cap, int _kph){
      SetAño(_año);
      SetCapDepo(_cap);
      SetLitrosDepo(0);
      SetKph(_kph);
      SetPropietario("");
   }

   Vehiculo(const Vehiculo &v){
      SetAño(v.año);
      SetCapDepo(v.capDepo);
      SetLitrosDepo(v.litrosDepo);
      SetKph(v.kph);
      SetPropietario((char*) v.propietario);
   }

//PUBLIC METHODS==========
public:
   void Imprimir();
   int LlenarDeposito(int litros);

//GETTERS=================
public:
   int GetAño(){
      return año;
   }
   int GetCapDepo(){
      return capDepo;
   }
   int GetLitrosDepo(){
      return litrosDepo;
   }
   int GetKph(){
      return kph;
   }
   char* GetPropietario(){
      return propietario;
   }

//SETTERS=================
public:
   void SetAño(int _año){
      año = _año;
   }
   void SetCapDepo(int _cap){
      capDepo = _cap;
   }
   void SetLitrosDepo(int _litros){
      litrosDepo = _litros;
      if (litrosDepo > GetCapDepo())
         SetLitrosDepo(GetCapDepo());
   }
   void SetKph(int _kph){
      kph = _kph;
   }
   void SetPropietario(char* _propietario){
      strcpy_s(propietario, _propietario);
   }
};


Y esto es los que sucede cuando genero el código:

1>Compilando...
1>Coche.cpp
1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\iostream(12) : error C2143: error de sintaxis : falta ';' delante de 'namespace'
1>c:\users\007\desktop\app\programacion c++\tema 9\ejercicio 2\ejercicio 2\coche.cpp(8) : error C2064: el término no se evalúa como una función con 0 argumentos
1>c:\users\007\desktop\app\programacion c++\tema 9\ejercicio 2\ejercicio 2\coche.cpp(9) : error C2064: el término no se evalúa como una función con 0 argumentos
1>Moto.cpp
1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\iostream(12) : error C2143: error de sintaxis : falta ';' delante de 'namespace'
1>c:\users\007\desktop\app\programacion c++\tema 9\ejercicio 2\ejercicio 2\moto.cpp(8) : error C2064: el término no se evalúa como una función con 0 argumentos
1>c:\users\007\desktop\app\programacion c++\tema 9\ejercicio 2\ejercicio 2\moto.cpp(9) : error C2064: el término no se evalúa como una función con 0 argumentos
1>Source.cpp
1>Vehiculo.cpp
1>Generando código...
1>El registro de compilación se guardó en el "file://c:\Users\007\Desktop\App\Programacion C++\Tema 9\Ejercicio 2\Ejercicio 2\Debug\BuildLog.htm"
1>Ejercicio 2 - 6 errores, 0 advertencias
========== Generar: 0 correctos, 1 incorrectos, 0 actualizados, 0 omitidos ==========

¿Como solucionaría esos errores?

Muchas gracias de antemano, y un gran saludo :D

ivancea96

Código (cpp) [Seleccionar]
void Imprimir();
     void SetMarca(char*);
     char* GetMarca();


Eso está en el "coche.h". No se si tendrá que ver con el error, pero, no tienes las funciones más que en el header.

xboxone007

Entonces tengo que poner las funciones en el coche.h. Lamento mi nivel de programación. y Muchas gracias por contestar.

nolasco281

#3
class Vehiculo{

private:
  int año;

Vehiculo(int _año, int _cap, int _kph){
     SetAño(_año);

Ese es el primero que veo no se si visual lo permite ñ o ese tipo de caracteres pero según yo no puede ser año, chécalo. Saludos te comento si encuentro más. Y asi todas las variables que lo tengan.

Hola ya solo me tira dos errores.

Hola no se que intentas hacer aca pero strcpy_s me dice que no esta declarada asi que debe de haber un problema ahi

Parece que el error que falta esta al rededor de esta funcion pero todavía no identifico donde.

y por que usas el char* _propietario. (puedes explicarme : ))

void SetPropietario(char* _propietario){
     strcpy_s(propietario, _propietario);
  }

parace que el ultimo error esta al rededor de propietario. y te soy sincero no lo identifico.  y recuerda comenta tu codigo para que otros entiendan que hacen algunas instrucciones saludos loco.



Una anotación amigo asumo que no lo sabes, pones el public después cada vez que va hacer algo nuevo, con el primer public es suficiente ya que lo que este abajo de este todo será público : )
Lo que se puede imaginar... se puede programar.

xboxone007

El "Vehiculo.h" y el "Vehiculo.cpp" son parte del ejercicio 1. Se que tiene que el coche y moto tiene que heredar de "Vehiculo", pero no se como. Sobre lo otros errores lo voy a ojear. Muchísimas gracias, enserio

nolasco281

Hola el problema no es la herencia sino las funciones que se declaran y heredan. Si haces un código más legible y como te comente antes y pones comentarios que especifiquen que hace cada método o función sería mejor para la gente y te ayudarían mas. Saludos.
Lo que se puede imaginar... se puede programar.

eferion

Cita de: nolasco281 en  3 Febrero 2014, 01:13 AM
Hola el problema no es la herencia sino las funciones que se declaran y heredan. Si haces un código más legible y como te comente antes y pones comentarios que especifiquen que hace cada método o función sería mejor para la gente y te ayudarían mas. Saludos.

Deberías hacer caso a este comentario, ya que la gente te ayuda de forma desinteresada no está de más facilitarles un poco la vida.

Voy a partir de la base de que has eliminado cualquier característica del código que no sea compatible con el habla inglesa ( 'ñ' por ejemplo ) y de que has hecho caso a los anteriores comentarios.

Clase básica de herencia (pero básica básica )

Lo primero de todo, para que una clase "herede" de otra es imprescindible que se refleje dicha relación en la declaración de la clase hija.

En el siguiente ejemplo, sacado de tu código, se puede ver una herencia mal hecha, bueno más bien es una falta de herencia:
Código (cpp) [Seleccionar]

class Moto{
  // ...
}


Según esto Moto es una clase independiente sin parentesco con el resto de clases de tu código. Sin embargo este problema tiene una sencilla aunque rebuscada solución ( nótese la ironía ):

Código (cpp) [Seleccionar]

class Moto: public Vehiculo {
  // ...
}


Ahora "Moto" hereda de "Vehículo"... y no solo eso, además la interfaz pública de "Vehículo" es también pública en "Moto"... maravillas de la ciencia.

Eso sí, si pruebas a compilar el código con este cambio verás que sigue fallando... es un error muy común, y precisamente por ello debes estar muy atento, olvidarse de terminar la declaración de una clase con un punto y coma... esto es:

Código (cpp) [Seleccionar]

class Moto: public Vehiculo {
  // ...
};


Ahora aplicas los mismos conocimientos a la clase "Coche" y tendrás los problemas relativos a herencia terminados.

Eso sí, el código seguirá sin funcionar... por que?? muy sencillo, para que una clase hija pueda "sustituir" una función de la clase padre, es imprescindible que se cumplan dos requisitos:


  • La firma de las funciones ha de ser la misma... es decir se tienen que llamar igual, retornar el mismo tipo de dato y tener la misma cantidad de argumentos, estando estos argumentos en el mismo orden.
  • El padre ha de tener etiquetada la función como virtual.

Si examinas la lista observarás que no cumples el segundo punto. Esto da como resultado que la función no se sustituya, sino que se oculte. Esto último provoca resultados inesperados y erróneos, por lo que conviene evitarlo.

Código (cpp) [Seleccionar]

class Vehiculo{
  // ...
  public:

    // ...

    virtual void Imprimir( );
    virtual void Settipo(char*);
    virtual char* Gettipo( );

    // ...
};


Si además, resulta que estas funciones han de ser, obligatoriamente, implementadas en las clases hijas, puedes convertir las funciones en virtuales puras de una forma muy sencilla:

Código (cpp) [Seleccionar]

class Vehiculo{
  // ...
  public:

    // ...

    virtual void Imprimir( ) = 0;
    virtual void Settipo(char*) = 0;
    virtual char* Gettipo( ) = 0;

    // ...
};


De esta forma, evitas, por un lado, tener que implementar las funciones en la clase "Vehiculo" y, por otro, obligas a tener que implementar las funciones en las clases que hereden de "Vehiculo".

Y con esto acaba la lección rápida sobre herencia. Espero que haya sido de vuestro agrado :).

Otras consideraciones

En estas cosas ya me meto menos porque ya dependen de factores como exigencias del guión ( requisitos, manias de los profesores, etc )... pero aún así me veo en la obligación de comentarlo:

* Deberías usar std::string en vez de char*... mi máxima es que si se usa C++ hay que usarlo con todas las consecuencias para aprovechar al máximo sus posibilidades y para conseguir la mejor base posible.

* Usa protección para evitar referencias múltiples.

Código (cpp) [Seleccionar]

#ifndef __VEHICULO__
#define __VEHICULO__

class Vehiculo
{
  // ...
};

#endif // __VEHICULO__


Código (cpp) [Seleccionar]

#pragma once

class Vehiculo
{
  // ...
};


Cualquiera de estos dos mecanismos evita que el mismo archivo de cabecera pueda ser cargado dos veces al compilar un archivo... este efecto se produce porque los includes son expandidos al compilar, si tu tienes en el main un include a "Coche" y a "Moto" y cada uno de estos tiene un include a "Vehiculo"... entonces "Vehiculo" aparecerá dos veces en main... y eso tirará un error.

* Usa el modificador const en aquellas funciones que no modifican el estado de la clase... esto mejora la legibilidad y usabilidad del código... además te ayudará a protegerte ante modificaciones que se produzcan "sin querer" o por un despiste.

* C++11 incluye el modificador override. Este modificador se puede poner en la declaración de las funciones virtuales de las clases hijas... lo que hace este modificador es asegurarse de que la función realmente es capaz de sustituir a la del padre... en caso contrario aparecerá un error de compilación:

Código (cpp) [Seleccionar]

class A
{
  public:
    virtual void func( );

    void func2( );
}

class B : public A
{
  public:
    void func( ) override;
    void func2( ) override;
};

class C : public A
{
  public
    virtual void fnuc( ) override;
};


En este ejemplo, se producirá un error al compilar la clase A, ya que la función "func2" no es virtual. También se producirá un error en C, ya que fnuc no forma parte de A.

Como ves todo son ventajas.

* Dentro de una clase, no es necesario usar "this->" para acceder a sus variables y funciones... el uso de "this" solo es necesario en un par de ocasiones contadas, en el resto de ocasiones lo puedes obviar... el código resultante será más legible.

Y bueno, por el momento creo que ya es suficiente chicha para hoy. Espero que mis comentarios te sean de utilidad.

Un saludo.