Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstring>
- #include <iostream>
- using std::cout;
- using std::endl;
- /*
- * Prosta lista jednokierunkowa z głębokim kopiowaniem
- */
- u_int32_t __STOS = 0;
- #define HERE "| " << __PRETTY_FUNCTION__ << ", linia " << __LINE__
- #define BEGIN( what ) \
- cout << "BEG " << what << "|" << __PRETTY_FUNCTION__ << ", linia " \
- << __LINE__ << " | poziom stosu " << ++__STOS << endl
- #define END( what ) \
- cout << "END " << what << "|" << __PRETTY_FUNCTION__ << ", linia " \
- << __LINE__ << " | poziom stosu " << __STOS-- << endl
- #define BEGINM( what ) \
- cout << "BEG " << what << "|" << __PRETTY_FUNCTION__ << ", linia " \
- << __LINE__ << " | poziom stosu " << ++__STOS << " | obiekt " << this \
- << endl
- #define ENDM( what ) \
- cout << "END " << what << "|" << __PRETTY_FUNCTION__ << ", linia " \
- << __LINE__ << " | poziom stosu " << __STOS-- << " | obiekt " << this \
- << endl
- /* ************************************************************************
- * W "pierwszym czytaniu możesz pominąć zrozumienie fragmentu odtąd do
- * drugiego takiego znacznika
- * ************************************************************************/
- class Wezel {
- private:
- char Napis[16]; /* Dana OSADZONA w węźle */
- Wezel* Nastepny; /* Wskaźnik na następny element albo nullptr */
- void dump( const char* msg = "" ) const; /* Wypisanie jednego poziomu węzła */
- public:
- /* Konstruktory */
- Wezel(); /* Konstruktor domyślny */
- Wezel( const char* _Napis ); /* Konstruktor z inicjalizacją napisu */
- /* Dwie formy kopiowania istniejącego obiektu */
- Wezel( const Wezel& oryginal ); /* Konstruktor kopiujący */
- Wezel& operator=( const Wezel& oryginal ); /* Operator przypisania */
- /* Destruktor */
- ~Wezel();
- /* Operator dołączenia elementu do listy
- *
- * W przeciwieństwie do zabaw z ostream z poprzedniego przykładu, tutaj
- * l1 << l2 jest metodą i jest zamieniane na l1.operator<<(l2)
- */
- Wezel& operator<<( Wezel* nowy );
- /* Funkcja wyświetla całą listę zaczynającą się od danego elementu
- * Nie chiałem tego robić na operatorze << z ostream, żeby nie mieszać
- */
- void wypisz();
- /* Wyszukuje i zwraca ostatni węzeł na liście */
- Wezel& ostatni();
- };
- void Wezel::dump( const char* msg ) const {
- if( Nastepny != nullptr ) {
- cout << msg << "Węzeł{adr=" << this << ", wart=\"" << Napis
- << "\", nast=" << Nastepny << "}" << endl;
- } else {
- cout << msg << "Węzeł{adr=" << this << ", wart=\"" << Napis
- << "\", brak_nast}" << endl;
- }
- }
- /* Tworzenie pustego elementu */
- Wezel::Wezel() : Nastepny( nullptr ) {
- // cout << "\tKonstruktor " << HERE << endl;
- BEGINM( "Konstruktor" );
- std::memset( Napis, 0, sizeof( Napis ) );
- dump( "\t\t" );
- ENDM( "Konstruktor" );
- }
- /* Tworzenie elementu z napisem */
- Wezel::Wezel( const char* _Napis ) : Nastepny( nullptr ) {
- // cout << "\tKonstruktor " << HERE << endl;
- BEGINM( "Konstruktor ze stringa" );
- std::strncpy( Napis, _Napis, sizeof( Napis ) );
- dump( "\t\t" );
- ENDM( "Konstruktor ze stringa" );
- }
- /* "Głębokie" kopiowanie elementu */
- Wezel::Wezel( const Wezel& oryginal ) {
- BEGINM( "Konstruktor kopiujący" );
- dump( "\t\tja: " );
- oryginal.dump( "\t\toryginał: " );
- std::memcpy( Napis, oryginal.Napis, sizeof( Napis ) );
- if( oryginal.Nastepny != nullptr ) {
- Nastepny = new Wezel( *oryginal.Nastepny );
- } else {
- Nastepny = nullptr;
- }
- ENDM( "Konstruktor kopiujący" );
- }
- /* Przypisanie elementu z głębokim kopiowaniem.
- *
- * Uwaga! Zaawansowana magia! Nie musisz tego teraz rozumieć !
- */
- Wezel& Wezel::operator=( const Wezel& oryginal ) {
- BEGINM( "Przypisanie" );
- dump( "\t\tja: " );
- oryginal.dump( "\t\toryginał: " );
- std::memcpy( Napis, oryginal.Napis, sizeof( Napis ) );
- /* Jeżeli po lewej stronie = jest już lista, to ją wyczyść */
- if( Nastepny != nullptr ) delete Nastepny;
- /* I przypisz nową */
- if( oryginal.Nastepny != nullptr ) {
- /* Jeżeli oryginał nie jest ostatni, to zrób nowy pusty element */
- Nastepny = new Wezel;
- /* "Głębokie" kopiowanie.
- *
- * Pamiętaj, że Nastepny i oryginal.Nastepny są wskaźnikami!
- *
- * Gdyby zlikwidować obie gwiazdki, to byłoby "płytkie" kopiowanie
- * samych adresów.
- * Dzięki gwiazdkom, wywołujemy operator= rekurencyjnie dla kolejnych
- * elementów listy
- */
- *Nastepny = *oryginal.Nastepny; /* "niewidzialna" rekurencja */
- } else {
- /* Jeżeli nie ma więcej nic do kopiowania */
- Nastepny = nullptr;
- }
- ENDM( "Przypisanie" );
- return *this; /* Żeby można było robić a = b = c */
- }
- /* Destruktor */
- Wezel::~Wezel() {
- BEGINM( "Destruktor" );
- dump( "\t\t" );
- /* Ususwaj wszystko do końca listy */
- if( Nastepny != nullptr ) delete Nastepny;
- ENDM( "Destruktor" );
- }
- /* Dopisanie elementu listy */
- Wezel& Wezel::operator<<( Wezel* nowy ) {
- BEGINM( "Dopisanie" );
- dump( "\t\t" );
- if( Nastepny != nullptr ) delete Nastepny;
- Nastepny = nowy;
- ENDM( "Dopisanie" );
- return *nowy; /* Można zrobić l1 << new l2 << new l3; */
- }
- /* Wypisanie listy */
- void Wezel::wypisz() {
- auto wskaznik = this; /* Zaczynamy od samego siebie */
- cout << "\tLista:" << endl;
- /* Powtarzaj, dopóki nie dojdziesz do końca */
- do {
- wskaznik->dump( "\t\t" );
- wskaznik = wskaznik->Nastepny;
- } while( wskaznik != nullptr );
- cout << "\tKoniec listy" << endl << endl;
- }
- /* Szukanie ostatniego */
- Wezel& Wezel::ostatni() {
- if( Nastepny != nullptr )
- /* Jeżeli jest jakiś następny, to może on jest ostatni? */
- return Nastepny->ostatni();
- else
- /* Nie ma następnego, my jesteśmy ostatni */
- return *this;
- }
- /* ************************************************************************
- * Tutaj zaczynają się funkcje, których działanie chcemy testować
- * ************************************************************************/
- void argument_kopia( Wezel arg ) {
- BEGIN( "przez wartość" );
- cout << "\t\tPrzed zmianą: ";
- arg.wypisz();
- arg.ostatni() << new Wezel( "kopia" );
- cout << "\t\tPo zmianie: ";
- arg.wypisz();
- END( "przez wartość" );
- }
- void argument_referencja( Wezel& arg ) {
- BEGIN( "przez referencję" );
- cout << "\t\tPrzed zmianą: ";
- arg.wypisz();
- arg.ostatni() << new Wezel( "referencja" );
- cout << "\t\tPo zmianie: ";
- arg.wypisz();
- END( "przez referencję" );
- }
- void argument_wskaznik( Wezel* arg ) {
- BEGIN( "przez wskaźnik" );
- cout << "\t\tPrzed zmianą: ";
- arg->wypisz();
- arg->ostatni() << new Wezel( "Wskaznik" );
- cout << "\t\tPo zmianie: ";
- arg->wypisz();
- END( "przez wskaźnik" );
- }
- int main( int argc, char* argv[] ) {
- BEGIN( "PROGRAM" );
- cout << "************************************************" << endl;
- cout << "Konstrukcja baza " << HERE << endl;
- Wezel baza( "Bazowy" );
- cout << "************************************************" << endl;
- cout << "Konstrukcja dodatkowych zmiennych " << HERE << endl;
- Wezel wart, ref, wsk;
- wart.wypisz();
- ref.wypisz();
- wsk.wypisz();
- cout << "************************************************" << endl;
- cout << "Dołączenie nowych węzłów do baza " << HERE << endl;
- baza << new Wezel( "nowy1" ) << new Wezel( "nowy2" );
- cout << "Po dopisaniu baza=";
- baza.wypisz();
- cout << "************************************************" << endl;
- cout << "Wywołanie funkcji 'przez wartość' " << HERE << endl;
- cout << "Kopiowanie bazy" << endl;
- wart = baza;
- cout << "Przed wywołaniem=";
- wart.wypisz();
- cout << ">>> Wołanie funkcji" << endl;
- argument_kopia( wart );
- cout << "<<< po powrocie=";
- wart.wypisz();
- cout << "************************************************" << endl;
- cout << "Wywołanie funkcji 'przez referencję'" << HERE << endl;
- cout << "Kopiowanie bazy" << endl;
- ref = baza;
- cout << "Przed wywołaniem=";
- ref.wypisz();
- cout << ">>> Wołanie funkcji" << endl;
- argument_referencja( ref );
- cout << "<<< po powrocie=";
- ref.wypisz();
- cout << "************************************************" << endl;
- cout << "Wywołanie funkcji 'przez wskaźnik'" << HERE << endl;
- cout << "Kopiowanie bazy" << endl;
- wsk = baza;
- cout << "Przed wywołaniem=";
- wsk.wypisz();
- cout << ">>> Wołanie funkcji" << endl;
- argument_wskaznik( &wsk );
- cout << "<<< po powrocie=";
- wsk.wypisz();
- cout << "************************************************" << endl;
- cout << "Wywołanie funkcji 'przez wartość' dla obiektu tymczasowego " << HERE
- << endl;
- argument_kopia( Wezel( "Tymczasowy1" ) );
- cout << "************************************************" << endl;
- END( "PROGRAM" );
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement