0 Daumen
511 Aufrufe

C++ Frage mit der Verwendung von Vektoren und einer Ausgabe in ein File:

1.Wie schreibe ich eine Klasse, welche eine Immobilie (mit Adresse, Baujahr und Besitzer) repräsentiert und auch zwei Methoden bereitstellt, um eine Instanz dieser Klasse mit entsprechenden Werten zu belegen (z.B. Methoden : : eingabe ( ) und : : ausgabe ()

2.Wie leite ich von der Klasse Immobilie zwei weitere Klassen für eine Wohn- und Geschäftsimmobilie ab. Die Klasse Wohnimmobilie enthalte eine zusätzliche Eigenschaft, die anzeigt, ob es sich um eine Wohnung oder um ein Haus handelt. Die Klasse Geschäftsimmobilie enthalte eine zusätzliche Eigenschaft, die anzeigt, ob in der Immobilie auch Wohnungen enthalten sind.
3.Wie nutze ich diese Klassen in einem Programm, welches nach einer Zahl \( \mathrm{n} \) fragt, und dann zur Eingabe der Daten von \( \mathrm{n} \) Immobilien auffordert, und diese dann in umgekehrter Reihenfolge wieder ausgibt. Vor jeder Eingabe sollte abgefragt werden, um welchen Typ von Immobilie es sich handelt.
4.Unser Programm sollte über die entsprechenden \( . \mathrm{h} \) und \( . \mathrm{cc} \) Dateien verteilt sein und über ein Makefile kompiliert werden.

Avatar von
3.Wie nutze ich diese Klassen in einem Programm, welches nach einer Zahl \( \mathrm{n} \) fragt, und dann zur Eingabe der Daten von \( \mathrm{n} \) Immobilien auffordert, und diese dann in umgekehrter Reihenfolge wieder ausgibt.

Wie soll bei der Eingabe zwischen Wohn- und Geschäftsimmobilie unterschieden werden?

Und wie weit bist Du schon?

#include<iostream>
using namespace std;

class Immobilie{
public:
int n;
int baujahr;
string adresse;
string besitzer;
void eingabe();
void ausgabe();
};
void Immobilie::eingabe(){
cout<<"Geben Sie ein Zahl:"<<'\n';
cin>>n;
}
void Immobilie::ausgabe(){
if(n%=2)
cout<<"Es handelt sich um eine Wohnung"<<'\n';
else
cout<<"Es handelt sich um ein Haus"<<'\n';
}

Es würde nicht gesagt wie wird es unterscheiden, deshalb habe ich selbst eine Eingabe überlegt, wenn die Eingabe gerade dann wird Wohnimmobilie und wenn ungerade ist dann Geschäftsimmobilie.

Ich habe schon die Immobilie klasse geschrieben aber ich kann leider nicht weiterkommen!

1 Antwort

+1 Daumen
 
Beste Antwort

Hallo,

bei solchen Frage ist es für den Antwortenden am einfachsten das Programm einfach 'hinzuklatschen'  ;-). Das mache ich jetzt einfach mal. Da Du wahrscheinlich Anfänger(in) bist, wirst Du einiges davon nicht verstehen.

Aufgaben dieser Art sind im Grunde für den Anfänger ungeeignet. Es enthält in einer mehr oder weniger professionellen Lösung bereits viel zu viele Programmiermuster, die man kennen müsste!

Die Aufteilung in Dateien überlasse ich Dir. Du solltest es in 4 .cc- und 3 .h-Dateien unterbringen.

Du hast garantiert Fragen ;-)


#include <iostream>
#include <memory>  // std::unique_ptr<>
#include <string>
#include <vector>

using namespace std; // nie im Header !!

class Immobilie {
public:
virtual ~Immobilie() = 0 {} // virtual wegen Ableiten

// Eingabe über friend-Funktion
friend std::istream& operator>>( std::istream& in, Immobilie& immo )
{
    immo.do_eingabe( in );
    return in;
}

// Ausgabe über friend-Funktion
friend std::ostream& operator<<( std::ostream& out, const Immobilie& immo )
{
    immo.do_ausgabe( out ); // hier wird ggf. die abgeleitete Methode aufgerufen
    return out;
}

protected:
  Immobilie() = default; // ist protected, um sicher zu stellen, dass nur eine abgeleitete Klasse angelegt werden kann
  virtual void do_eingabe( std::istream& in )
  {
      std::getline( std::getline( in >> std::ws, adresse ) >> baujahr >> std::ws, besitzer );
  }
  virtual void do_ausgabe( std::ostream& out ) const
  {
      out << "Addr.: " << adresse << "\n";
      out << "Baujahr: " << baujahr << "\n";
      out << "Besitzer: " << besitzer << "\n";
  }

private:
// int n; // das ist unnötig, da dies über die Klasse definiert ist
std::string adresse;  // benutze in Header-Dateien den Prefix std::
int baujahr;  // mache die Member private
string besitzer;
};

class Wohnimmobilie : public Immobilie {
public:
  enum class Art { Wohnung, Haus };
  Wohnimmobilie() = default;

protected:
  void do_eingabe( std::istream& in ) override
  {
      Immobilie::do_eingabe( in );
      int artFlag;
      if( in >> artFlag )
          m_art = artFlag > 0? Art::Haus: Art::Wohnung;
  }
  void do_ausgabe( std::ostream& out ) const override
  {
      Immobilie::do_ausgabe( out ); // erst den allgemeinen Teil
      out << (m_art == Art::Wohnung? "Wohnung": "Haus") << "\n";
  }
private:
  Art m_art;
};

class Geschaeftsimmobilie : public Immobilie {
public:
  enum class Wohnung { vorhanden, keine };
  Geschaeftsimmobilie() = default;

protected:
  void do_eingabe( std::istream& in ) override
  {
      Immobilie::do_eingabe( in );
      int wohnungFlag;
      if( in >> wohnungFlag )
          wohnung_vorhanden = wohnungFlag > 0? Wohnung::vorhanden: Wohnung::keine;
  }
  void do_ausgabe( std::ostream& out ) const override
  {
      Immobilie::do_ausgabe( out ); // erst den allgemeinen Teil
      out << "Geschaeft " << (wohnung_vorhanden == Wohnung::vorhanden? "mit Wohnung": "") << "\n";
  }

private:
  Wohnung wohnung_vorhanden;
};

int main()
{
  std::vector< std::unique_ptr< Immobilie > > alleImmobilien;
  cout << "Geben Sie so viele Wohnungen ein, wie Sie wollen! bis 0" << endl;
  for( int n; cout << "...> ", cin >> n; )
  {
      if( n == 0 )
          break; // ... und fertig
      std::unique_ptr< Immobilie > immo;
      if( n%2 == 0 ) // gerade Zahl -> Wohnimmobilie
      {
          cout << "Wohnimmobilie:\n";
          immo = std::make_unique< Wohnimmobilie >();
      }
      else // ungerade -> Geschäftsimmobilie
      {
          cout << "Geschaeftsimmobilie:\n";
          immo = std::make_unique< Geschaeftsimmobilie >();
      }
      if( cin >> *immo )
          alleImmobilien.emplace_back( std::move(immo) );
  }
  cout << "\nes wurden " << alleImmobilien.size() << " Immobilien eingegeben" << endl;
  for( auto i = alleImmobilien.rbegin(); i != alleImmobilien.rend(); ++i ) // in umgekehrter Reihenfolge
  {
      cout << **i << endl;
  }
  return 0;
}

Das Programm beendet sich, wenn man bei der Eingabe einen Fehler macht, oder wenn man als Immobilien-Typ eine 0 eingibt.

und so könnte eine Dialog mit diesem Programm aussehen:

Geben Sie so viele Wohnungen ein, wie Sie wollen! bis 0
...> 2
Wohnimmobilie:
Kreuzstr. 89
2001
Max Mustermann
2
...> 1
Geschaeftsimmobilie:
Hauptstr. 3
1970
Hein Bloed
0
...> 2
Wohnimmobilie:
Blumenweg 1
1999
Rita Rot
0
...> 0

es wurden 3 Immobilien eingegeben
Addr.: Blumenweg 1
Baujahr: 1999
Besitzer: Rita Rot
Wohnung

Addr.: Hauptstr. 3
Baujahr: 1970
Besitzer: Hein Bloed
Geschaeft

Addr.: Kreuzstr. 89
Baujahr: 2001
Besitzer: Max Mustermann
Haus

Avatar von

.. ich habe noch mal eine Kleinigkeit überarbeitet.

Ja, vielen Dank. ich versuche es gerade in 3 verschiedene Klassen zu schreiben damit ich die mit .h und .cc miteinander zu verbinden aber es klappt nicht.

Weißt du was ich in .h File schreiben muss damit ich alle 3 mit einander zu verbinden?

Weißt du was ich in .h File schreiben muss damit ich alle 3 mit einander zu verbinden?

Nichts! Das 'Verbinden' erledigt der Linker. Und der verbindet keine .h-Files sondern Object-FIles, die der Compiler aus den .cc-Files generiert. Die .cc-Files inkludieren die .h-Files über das #include-Statement.

Welche Dateien zu einem ausführbaren Programm 'verbunden' werden, wird im Makefile festgelegt.

Wie äußert sich denn ...

... aber es klappt nicht.

... genau ??

Ja, z.B. wenn ich die Wohnimmobilie als einzige Object-File schreiben will und es mit den anderen Object-File inkludieren, also was muss ich in .f-File schreiben. Könntest du mir vielleicht das mehr erklären?

Die Object-Files erzeugt nur der Compiler aus den .cc-Files. Die schreibst Du nicht.

Die Wohnimmobilie sieht etwa so aus in .h und .cc:

// --- H-File Wohnimmobilie.h
#include "Immobilie.h"

class Wohnimmobilie : public Immobilie {
public:
  enum class Art { Wohnung, Haus };
  Wohnimmobilie() = default;
protected:  
void do_eingabe( std::istream& in ) override;
  void do_ausgabe( std::ostream& out ) const override;
private:
  Art m_art;
};


... und das .cc-File dazu

// -- .CC-File Wohnimmobile.cc
#include "Wohnimmobilie.h"

void Wohnimmobilie::do_eingabe( std::istream& in )
{
  Immobilie::do_eingabe( in );
  int artFlag;
  if( in >> artFlag )
      m_art = artFlag > 0? Art::Haus: Art::Wohnung;
}
void Wohnimmobilie::do_ausgabe( std::ostream& out ) const
{
  Immobilie::do_ausgabe( out ); // erst den allgemeinen Teil
  out << (m_art == Art::Wohnung? "Wohnung": "Haus") << "\n";
}


Die Geschäftsimmobile sieht im Prinzip genauso aus. Alle Deklarationen wandern in das .h-File alle Implementierungen in das .cc-File. Bei der Immobilie.h muss <string>, <istream> und <ostream> inkludiert werden. Und im main.cc wird alles zusammengefasst:

// ---- main.cc 
#include "Wohnimmobilie.h"
#include "Geschaeftsimmobile.h"
#include <iostream>  // fuer cout, cin
#include <memory>  // std::unique_ptr<>
#include <vector>

int main()
{
  using namespace std; // hier macht das jetzt Sinn!
  vector< unique_ptr< Immobilie > > alleImmobilien;
  cout << "Geben Sie so viele Wohnungen ein, wie Sie wollen! bis 0" << endl;
  // usw. wie oben

  return 0;
}

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community