Warto zrobić na początek porządek z tym kodem:
Jeśli chcesz aby kod był ponownie używany, lepiej jednak nie deklarować na początku użycia przestrzeni nazewniczej std. Tu można dyskutować w jakim przypadku i przy jakiej objętości kodu...
Brakuje Ci nagłówka string.
Dobrą zasadą jest deklarowanie zmiennych w nowej linii. To się łatwiej czyta i nie popełni się błędu jeśli typ będzie skomplikowany (np. wskaźnik).
Dobrą zasadą jest przyjęcie łamania linii na określonej kolumnie. Tu złamię (co jest najczęściej wykładnią) na 80.
Inicjalizacja atrybutów klasy powinna odbywać się w liście inicjalizacji.
Jeśli hermetyzujesz, umieść atrybuty w sekcjach private.
Stosu const correctness tam gdzie to możliwe.
Po co kopiować std::string w argumencie? Wystarczy przekazać referencję na stałą.
Na początek, aby mocno nie zmieniać kodu, dostęp do atrybutów w klasie Pojazd można deklarować jako protected (później można to ew zmienić).
Znaków nowej linii raczej nie wprowadza się na początku tekstu a w częściej na końcu. I nie jest to std::endl. Wystarcza znak nowej linii (to kiedy konieczne jest std::endl które realizuje std::flush, to poza tym przykładem)
Powstaje sensowne pytanie czy zajdzie przypadek tworzenia "pustego autobusu". To co robisz konstruktorem domyślnym (czyli bez argumentów). Jeśli nie zajdzie taki przypadek, warto poinformować kompilator że nawet gdy go przypadkowo użyjesz, to będzie błąd.
W zasadzie nie zmieniłem działania Twojego kodu. Wygląda tak:
#include <iostream>
#include <string>
//Bazowy Pojazd
class Pojazd {
public:
Pojazd () = delete;
Pojazd (const std::string & pMarka, const std::string & pModel, int pRok_pr)
: marka{pMarka}, model{pModel}, rok_pr{pRok_pr} {}
void wyswietl () const {
std::cout << "Dane:\n Marka: " << marka << "\n Model: " << model
<< "\n Rok produkcji: " << rok_pr << '\n';
}
protected:
std::string marka;
std::string model;
int rok_pr;
};
//Autobus
class Autobus : public Pojazd {
public:
Autobus () = delete;
Autobus (const std::string & pMarka, const std::string & pModel, int pRok_pr,
int pMiej_siedz, int pMiej_stoj)
: Pojazd (pMarka, pModel, pRok_pr), miej_siedz{pMiej_siedz}
, miej_stoj{pMiej_stoj} {}
void wyswietl () const {
std::cout << "Dane:\n Marka: " << marka << "\n Model: " << model
<< "\n Rok produkcji: " << rok_pr << "\n Miejsca siedzace: "
<< miej_siedz << "\n Miejsca stojace: " << miej_stoj << '\n';
}
private:
int miej_siedz;
int miej_stoj;
};
//Ciezarowka
class Ciezarowka : public Pojazd {
public:
Ciezarowka () = delete;
Ciezarowka (const std::string & pMarka, const std::string & pModel,
int pRok_pr, const std::string & pCysterna,
const std::string & pChlodnia,
const std::string & pWywrotka)
: Pojazd (pMarka, pModel, pRok_pr), cysterna{pCysterna},
chlodnia{pChlodnia}, wywrotka{pWywrotka} {}
void wyswietl() const {
std::cout << "Dane:\n Marka: " << marka << "\n Model: " << model
<< "\n Rok produkcji: " << rok_pr << "\n Cysterna: "
<< cysterna << "\n Chlodnia: " << chlodnia
<< "\n Wywrotka: " << wywrotka << '\n';
}
private:
std::string cysterna;
std::string wywrotka;
std::string chlodnia;
};
//Main
int main () {
std::string sMarka;
std::string sModel;
std::string sCysterna;
std::string sChlodnia;
std::string sWywrotka;
int sRok_pr;
int sMiej_siedz;
int sMiej_stoj;
std::cout << "Wprowadz Marke: ";
std::cin >> sMarka;
std::cout << "Wprowadz model: ";
std::cin >> sModel;
std::cout << "Wprowadz rok produkcji: ";
std::cin >> sRok_pr;
std::cout << "Wprowadz miejsca siedzace: ";
std::cin >> sMiej_siedz;
std::cout << "Wprowadz miejsca stojace: ";
std::cin >> sMiej_stoj;
Autobus bus(sMarka, sModel, sRok_pr, sMiej_siedz, sMiej_stoj);
bus.wyswietl();
return 0;
}
Teraz powstaną pytania:
- Czy markę i model należy zmieniać w trakcie działania aplikacji? Czy tak łatwo ten sam egzemplarz pojazdu, zmienić na inną markę?
- Na ile klasa Pojazd powinna udostępniać możliwość dostępu i ew. zmiany atrybutów?
Na pierwsze pytanie można odpowiedzieć że nie! Nie zmienisz Opla w Mercedesa ... w tym samym egzemplarzu. Toteż pola marka i model powinny być stałe. A co z rokiem? Hmm... nie chodzi o aplikację dla oszustów, ale rzeczywiście po zmianie ramy, karoserii i silnika, może się zmienić rocznik. Więc warto dać dostęp do zmiany rocznika.
Na pytanie drugie... Jeśli powinna dawać możliwość zmiany i dostępu, to tylko dla swoich potomków. Stąd nie będzie dostępu publicznego do pól. I to tak w trybie odczytu jak i zapisu. Widoczność metod dostępowych będzie protected a same atrybuty prywatne.
Dla porządku o czym mówię, kod:
#include <iostream>
#include <string>
//Bazowy Pojazd
class Pojazd {
public:
Pojazd () = delete;
Pojazd (const std::string & pMarka, const std::string & pModel, int pRok_pr)
: marka{pMarka}, model{pModel}, rok_pr{pRok_pr} {}
void wyswietl () const {
std::cout << "Dane:\n Marka: " << marka << "\n Model: " << model
<< "\n Rok produkcji: " << rok_pr << '\n';
}
protected:
const std::string & get_marka() const {
return marka;
}
const std::string & get_model() const {
return model;
}
const int get_rok_pr() const {
return rok_pr;
}
void set_rok_pr(int rok) {
rok_pr = rok;
}
private:
const std::string marka;
const std::string model;
int rok_pr;
};
//Autobus
class Autobus : public Pojazd {
public:
Autobus () = delete;
Autobus (const std::string & pMarka, const std::string & pModel, int pRok_pr,
int pMiej_siedz, int pMiej_stoj)
: Pojazd (pMarka, pModel, pRok_pr), miej_siedz{pMiej_siedz}
, miej_stoj{pMiej_stoj} {}
void wyswietl () const {
std::cout << "Dane:\n Marka: " << get_marka() << "\n Model: "
<< get_model() << "\n Rok produkcji: " << get_rok_pr()
<< "\n Miejsca siedzace: " << miej_siedz
<< "\n Miejsca stojace: " << miej_stoj << '\n';
}
private:
int miej_siedz;
int miej_stoj;
};
//Ciezarowka
class Ciezarowka : public Pojazd {
public:
Ciezarowka () = delete;
Ciezarowka (const std::string & pMarka, const std::string & pModel,
int pRok_pr, const std::string & pCysterna,
const std::string & pChlodnia,
const std::string & pWywrotka)
: Pojazd (pMarka, pModel, pRok_pr), cysterna{pCysterna},
chlodnia{pChlodnia}, wywrotka{pWywrotka} {}
void wyswietl() const {
std::cout << "Dane:\n Marka: " << get_marka() << "\n Model: "
<< get_model() << "\n Rok produkcji: " << get_rok_pr()
<< "\n Cysterna: " << cysterna << "\n Chlodnia: "
<< chlodnia << "\n Wywrotka: " << wywrotka << '\n';
}
private:
std::string cysterna;
std::string wywrotka;
std::string chlodnia;
};
//Main
int main () {
std::string sMarka;
std::string sModel;
std::string sCysterna;
std::string sChlodnia;
std::string sWywrotka;
int sRok_pr;
int sMiej_siedz;
int sMiej_stoj;
std::cout << "Wprowadz Marke: ";
std::cin >> sMarka;
std::cout << "Wprowadz model: ";
std::cin >> sModel;
std::cout << "Wprowadz rok produkcji: ";
std::cin >> sRok_pr;
std::cout << "Wprowadz miejsca siedzace: ";
std::cin >> sMiej_siedz;
std::cout << "Wprowadz miejsca stojace: ";
std::cin >> sMiej_stoj;
Autobus bus(sMarka, sModel, sRok_pr, sMiej_siedz, sMiej_stoj);
bus.wyswietl();
return 0;
}
No to teraz Autobus.
Załóżmy że można w autobusie zmienić ilość miejsc siedzących i stojących. Tu można pobawić się w implementację maksymalnej ilości miejsc siedzących i stojących. Tak aby nie można było "demolować autobusu" :) Potrzebne będą get/set dla tych atrybutów. Tu mogą być publiczne.
Tu akurat zmiany są proste. Kod więc dalej...
Co jednak z Ciężarówką? W Twojej implementacji, może ona być równocześnie i wywrotką i chłodnią i cysterną. Albo rozdziel je na oddzielne klasy (jeśli każdy z tych pojazdów wymaga innej implementacji), albo dodaj opcję przekazywania innej przestrzeni załadunkowej. Ta ostatnia, to może być oddzielna klasa. Tu uproszczę przekazując std::string z opisem.
Znów... dostęp do pola "rodzaj", powinien być raczej tylko do odczytu (chłodnię trudno przerobić na wywrotkę). Stąd jedynie getter.
No to kod:
#include <iostream>
#include <string>
//Bazowy Pojazd
class Pojazd {
public:
Pojazd () = delete;
Pojazd (const std::string & pMarka, const std::string & pModel, int pRok_pr)
: marka{pMarka}, model{pModel}, rok_pr{pRok_pr} {}
void wyswietl () const {
std::cout << "Dane:\n Marka: " << marka << "\n Model: " << model
<< "\n Rok produkcji: " << rok_pr << '\n';
}
protected:
const std::string & get_marka() const {
return marka;
}
const std::string & get_model() const {
return model;
}
const int get_rok_pr() const {
return rok_pr;
}
void set_rok_pr(int rok) {
rok_pr = rok;
}
private:
const std::string marka;
const std::string model;
int rok_pr;
};
//Autobus
class Autobus : public Pojazd {
public:
Autobus () = delete;
Autobus (const std::string & pMarka, const std::string & pModel, int pRok_pr,
int pMiej_siedz, int pMiej_stoj)
: Pojazd (pMarka, pModel, pRok_pr), miej_siedz{pMiej_siedz}
, miej_stoj{pMiej_stoj} {}
void wyswietl () const {
std::cout << "Dane:\n Marka: " << get_marka() << "\n Model: "
<< get_model() << "\n Rok produkcji: " << get_rok_pr()
<< "\n Miejsca siedzace: " << miej_siedz
<< "\n Miejsca stojace: " << miej_stoj << '\n';
}
const int get_miej_siedz() const {
return miej_siedz;
}
const int get_miej_stoj() const {
return miej_stoj;
}
void set_miej_siedz(int miejsca) {
miej_siedz = miejsca;
}
void set_miej_stoj(int miejsca) {
miej_stoj = miejsca;
}
private:
int miej_siedz;
int miej_stoj;
};
//Ciezarowka
class Ciezarowka : public Pojazd {
public:
Ciezarowka () = delete;
Ciezarowka (const std::string & pMarka, const std::string & pModel,
int pRok_pr, const std::string & pRodzaj)
: Pojazd (pMarka, pModel, pRok_pr), rodzaj{pRodzaj} {}
void wyswietl() const {
std::cout << "Dane:\n Marka: " << get_marka() << "\n Model: "
<< get_model() << "\n Rok produkcji: " << get_rok_pr()
<< "\n Rodzaj: " << rodzaj << '\n';
}
const std::string & get_rodzaj() const {
return rodzaj;
}
private:
const std::string rodzaj;
};
//Main
int main () {
std::string sMarka;
std::string sModel;
std::string sCysterna;
std::string sChlodnia;
std::string sWywrotka;
int sRok_pr;
int sMiej_siedz;
int sMiej_stoj;
std::cout << "Wprowadz Marke: ";
std::cin >> sMarka;
std::cout << "Wprowadz model: ";
std::cin >> sModel;
std::cout << "Wprowadz rok produkcji: ";
std::cin >> sRok_pr;
std::cout << "Wprowadz miejsca siedzace: ";
std::cin >> sMiej_siedz;
std::cout << "Wprowadz miejsca stojace: ";
std::cin >> sMiej_stoj;
Autobus bus(sMarka, sModel, sRok_pr, sMiej_siedz, sMiej_stoj);
bus.wyswietl();
return 0;
}