MeehoweCK Temat założony przez niniejszego użytkownika |
Kompilowanie w visualu » 2018-06-03 14:29:22 Cześć Napisałem taki oto kod (dla celów szkoleniowych), który działa bez zarzutu dla kompilatora gnu. Problem w tym, że wykładowca życzy sobie, aby działał pod visualem, a tam pojawia się jakiś błąd i to nawet nie w fazie kompilacji, ale już przy wypisaniu na konsolę. #include <string> #include <iostream>
using namespace std;
class Silnik { protected: double moc; double wymiary; public: Silnik(); Silnik( double, double ); Silnik( const Silnik & ); virtual ~Silnik(); double get_moc(); void set_moc( double ); double get_wymiary(); void set_wymiary( double ); virtual void wypisz(); Silnik * nast; void dodaj( Silnik * ); void wypiszWiekszyNiz( double ); void wypiszListe(); virtual Silnik & operator +=( const Silnik & ); virtual Silnik & operator =( const Silnik & ); };
class Elektryczny : public Silnik { protected: double napiecie; double bateria; public: Elektryczny(); Elektryczny( double, double, double, double ); Elektryczny( const Elektryczny & ); Elektryczny( const Silnik & ); ~Elektryczny(); double get_napiecie(); void set_napiecie( double ); double get_bateria(); void set_bateria( double ); void wypisz(); Elektryczny & operator +=( const Elektryczny & ); Elektryczny & operator =( const Elektryczny & ); };
Silnik::Silnik() : moc( 6 ) , wymiary( 0 ) , nast( nullptr ) { }
Silnik::Silnik( double a_moc, double a_wymiary ) : moc( a_moc ) , wymiary( a_wymiary ) , nast( nullptr ) { }
Silnik::Silnik( const Silnik & obiekt ) : moc( obiekt.moc ) , wymiary( obiekt.wymiary ) { if( obiekt.nast ) nast = new Silnik( * obiekt.nast ); else nast = nullptr; }
Silnik::~Silnik() { if( nast ) delete nast; }
double Silnik::get_moc() { return moc; }
void Silnik::set_moc( double s_moc ) { moc = s_moc; }
double Silnik::get_wymiary() { return wymiary; }
void Silnik::set_wymiary( double s_wymiary ) { wymiary = s_wymiary; }
void Silnik::wypiszListe() { wypisz(); if( nast ) nast->wypiszListe(); }
void Silnik::wypisz() { cout << "Silnik" << endl; cout << "Moc silnika: " << moc << endl; cout << "Wymiary silnika: " << wymiary << endl; }
void Silnik::dodaj( Silnik * nowy ) { if( nast == nullptr ) nast = nowy; else nast->dodaj( nowy ); }
void Silnik::wypiszWiekszyNiz( double liczba ) { if( moc > liczba ) wypisz(); if( nast ) nast->wypiszWiekszyNiz( liczba ); }
Silnik & Silnik::operator +=( const Silnik & obiekt ) { moc += obiekt.moc; wymiary += obiekt.wymiary; return * this; }
Silnik & Silnik::operator =( const Silnik & obiekt ) { if( this != & obiekt ) { moc = obiekt.moc; wymiary = obiekt.wymiary; } return * this; }
Elektryczny::Elektryczny() : Silnik() , napiecie( 0 ) , bateria( 0 ) { }
Elektryczny::Elektryczny( double a_napiecie, double a_bateria, double a_moc, double a_wymiary ) : Silnik( a_moc, a_wymiary ) , napiecie( a_napiecie ) , bateria( a_bateria ) { }
Elektryczny::Elektryczny( const Elektryczny & obiekt ) : Silnik( obiekt.moc, obiekt.wymiary ) , napiecie( obiekt.napiecie ) , bateria( obiekt.bateria ) { if( obiekt.nast ) nast = new Elektryczny( * obiekt.nast ); }
Elektryczny::Elektryczny( const Silnik & obiekt ) : Silnik( obiekt ) { }
Elektryczny::~Elektryczny() { if( nast ) delete nast; }
double Elektryczny::get_napiecie() { return napiecie; }
void Elektryczny::set_napiecie( double s_napiecie ) { napiecie = s_napiecie; }
double Elektryczny::get_bateria() { return wymiary; }
void Elektryczny::set_bateria( double s_bateria ) { bateria = s_bateria; }
void Elektryczny::wypisz() { cout << "Elektryczny" << endl; cout << "Moc silnika: " << moc << endl; cout << "Wymiary silnika: " << wymiary << endl; cout << "Napiecie: " << napiecie << endl; cout << "Czas pracy baterii: " << bateria << endl; }
Elektryczny & Elektryczny::operator +=( const Elektryczny & obiekt ) { moc += obiekt.moc; wymiary += obiekt.wymiary; napiecie += obiekt.napiecie; bateria += obiekt.bateria; return * this; }
Elektryczny & Elektryczny::operator =( const Elektryczny & obiekt ) { if( this != & obiekt ) { moc = obiekt.moc; wymiary = obiekt.wymiary; napiecie = obiekt.napiecie; bateria = obiekt.bateria; } return * this; }
template < class typ > typ sumuj( typ * head ) { typ * temp = head; typ wynik = * head; while( temp->nast ) { temp = dynamic_cast < typ *>( temp->nast ); wynik += * temp; } return wynik; }
int main() { Elektryczny * head = new Elektryczny( 1, 2, 13, 26 ); head->dodaj( new Elektryczny( 12, 28, 1, 35 ) ); head->dodaj( new Elektryczny( 1, 100, 235, 35 ) ); head->dodaj( new Elektryczny( 100, 200, 13, 356 ) ); head->wypiszListe(); cout << endl << "suma:" << endl; Elektryczny suma = sumuj( head ); suma.wypisz(); delete head; return 0; }
Chodzi konkretnie o instrukcję "Elektryczny suma = sumuj(head)". Okazuje się, że w visualu funkcja albo niepoprawnie zwraca obiekt, albo w ogóle go nie zwraca. Sprawdzałem i sama funkcja szablonowa działa dobrze (można sprawdzić wpisując "wynik.wypisz()" przed return), jednak po wyjściu z funkcji komenda "suma.wypisz()" nic nie robi - tak jakby nie miała czego wypisać. Gdzie leży różnica w interpretacji kodu przez GNU i przez Visual? |
|
pekfos |
» 2018-06-03 14:36:56 Wywal destruktor klasy Elektryczny. |
|
MeehoweCK Temat założony przez niniejszego użytkownika |
» 2018-06-03 14:54:56 Wielkie dzięki @pekfos. Czy możesz mi krótko wyjaśnić dlaczego ten destruktor wywoływał się jeszcze przed zwróceniem wyniku? I co gdyby w innej części kodu ten destruktor jednak był potrzebny? Destruktor klasy pochodnej nie jest wymagany do zwolnienia pamięci? |
|
pekfos |
» 2018-06-03 15:06:59 Klasa Elektryczny nie potrzebuje destruktora do niczego. Ten który napisałeś był błędny. Pamięć zostanie zwolniona przez destruktor klasy bazowej. Zwalniając to w klasie pochodnej powodowałeś zwolnienie 2 razy, wkraczałeś w kompetencje klasy bazowej i w gruncie rzeczy napisałeś kod bez sensu i sprzeczny z założeniami programowania obiektowego. |
|
« 1 » |