Advertisement
PKraszewski

Untitled

Aug 19th, 2016
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.06 KB | None | 0 0
  1. #include <cstring>
  2. #include <iostream>
  3.  
  4. using std::cout;
  5. using std::endl;
  6.  
  7. /*
  8.  * Prosta lista jednokierunkowa z głębokim kopiowaniem
  9.  */
  10.  
  11. u_int32_t __STOS = 0;
  12. #define HERE "| " << __PRETTY_FUNCTION__ << ", linia " << __LINE__
  13.  
  14. #define BEGIN( what )                                                \
  15.   cout << "BEG " << what << "|" << __PRETTY_FUNCTION__ << ", linia " \
  16.        << __LINE__ << " | poziom stosu " << ++__STOS << endl
  17.  
  18. #define END( what )                                                  \
  19.   cout << "END " << what << "|" << __PRETTY_FUNCTION__ << ", linia " \
  20.        << __LINE__ << " | poziom stosu " << __STOS-- << endl
  21.  
  22. #define BEGINM( what )                                                       \
  23.   cout << "BEG " << what << "|" << __PRETTY_FUNCTION__ << ", linia "         \
  24.        << __LINE__ << " | poziom stosu " << ++__STOS << " | obiekt " << this \
  25.        << endl
  26.  
  27. #define ENDM( what )                                                         \
  28.   cout << "END " << what << "|" << __PRETTY_FUNCTION__ << ", linia "         \
  29.        << __LINE__ << " | poziom stosu " << __STOS-- << " | obiekt " << this \
  30.        << endl
  31.  
  32. /* ************************************************************************
  33.  * W "pierwszym czytaniu możesz pominąć zrozumienie fragmentu odtąd do
  34.  * drugiego takiego znacznika
  35.  * ************************************************************************/
  36.  
  37. class Wezel {
  38.  private:
  39.   char   Napis[16]; /* Dana OSADZONA w węźle */
  40.   Wezel* Nastepny;  /* Wskaźnik na następny element albo nullptr */
  41.  
  42.   void dump( const char* msg = "" ) const; /* Wypisanie jednego poziomu węzła */
  43.  
  44.  public:
  45.   /* Konstruktory */
  46.   Wezel();                     /* Konstruktor domyślny */
  47.   Wezel( const char* _Napis ); /* Konstruktor z inicjalizacją napisu */
  48.  
  49.   /* Dwie formy kopiowania istniejącego obiektu */
  50.   Wezel( const Wezel& oryginal );            /* Konstruktor kopiujący */
  51.   Wezel& operator=( const Wezel& oryginal ); /* Operator przypisania */
  52.  
  53.   /* Destruktor */
  54.   ~Wezel();
  55.  
  56.   /* Operator dołączenia elementu do listy
  57.    *
  58.    * W przeciwieństwie do zabaw z ostream z poprzedniego przykładu, tutaj
  59.    * l1 << l2 jest metodą i jest zamieniane na l1.operator<<(l2)
  60.    */
  61.   Wezel& operator<<( Wezel* nowy );
  62.  
  63.   /* Funkcja wyświetla całą listę zaczynającą się od danego elementu
  64.    * Nie chiałem tego robić na operatorze << z ostream, żeby nie mieszać
  65.    */
  66.   void wypisz();
  67.  
  68.   /* Wyszukuje i zwraca ostatni węzeł na liście */
  69.   Wezel& ostatni();
  70. };
  71.  
  72. void Wezel::dump( const char* msg ) const {
  73.   if( Nastepny != nullptr ) {
  74.     cout << msg << "Węzeł{adr=" << this << ", wart=\"" << Napis
  75.          << "\", nast=" << Nastepny << "}" << endl;
  76.   } else {
  77.     cout << msg << "Węzeł{adr=" << this << ", wart=\"" << Napis
  78.          << "\", brak_nast}" << endl;
  79.   }
  80. }
  81.  
  82. /* Tworzenie pustego elementu */
  83. Wezel::Wezel() : Nastepny( nullptr ) {
  84.   // cout << "\tKonstruktor " << HERE << endl;
  85.   BEGINM( "Konstruktor" );
  86.   std::memset( Napis, 0, sizeof( Napis ) );
  87.   dump( "\t\t" );
  88.   ENDM( "Konstruktor" );
  89. }
  90.  
  91. /* Tworzenie elementu z napisem */
  92. Wezel::Wezel( const char* _Napis ) : Nastepny( nullptr ) {
  93.   // cout << "\tKonstruktor " << HERE << endl;
  94.   BEGINM( "Konstruktor ze stringa" );
  95.   std::strncpy( Napis, _Napis, sizeof( Napis ) );
  96.   dump( "\t\t" );
  97.   ENDM( "Konstruktor ze stringa" );
  98. }
  99.  
  100. /* "Głębokie" kopiowanie elementu */
  101. Wezel::Wezel( const Wezel& oryginal ) {
  102.   BEGINM( "Konstruktor kopiujący" );
  103.   dump( "\t\tja: " );
  104.   oryginal.dump( "\t\toryginał: " );
  105.  
  106.   std::memcpy( Napis, oryginal.Napis, sizeof( Napis ) );
  107.  
  108.   if( oryginal.Nastepny != nullptr ) {
  109.     Nastepny = new Wezel( *oryginal.Nastepny );
  110.   } else {
  111.     Nastepny = nullptr;
  112.   }
  113.   ENDM( "Konstruktor kopiujący" );
  114. }
  115.  
  116. /* Przypisanie elementu z głębokim kopiowaniem.
  117.  *
  118.  * Uwaga! Zaawansowana magia! Nie musisz tego teraz rozumieć !
  119.  */
  120. Wezel& Wezel::operator=( const Wezel& oryginal ) {
  121.   BEGINM( "Przypisanie" );
  122.   dump( "\t\tja: " );
  123.   oryginal.dump( "\t\toryginał: " );
  124.  
  125.   std::memcpy( Napis, oryginal.Napis, sizeof( Napis ) );
  126.  
  127.   /* Jeżeli po lewej stronie = jest już lista, to ją wyczyść */
  128.  
  129.   if( Nastepny != nullptr ) delete Nastepny;
  130.  
  131.   /* I przypisz nową */
  132.   if( oryginal.Nastepny != nullptr ) {
  133.     /* Jeżeli oryginał nie jest ostatni, to zrób nowy pusty element */
  134.     Nastepny = new Wezel;
  135.  
  136.     /* "Głębokie" kopiowanie.
  137.      *
  138.      * Pamiętaj, że Nastepny i oryginal.Nastepny są wskaźnikami!
  139.      *
  140.      * Gdyby zlikwidować obie gwiazdki, to byłoby "płytkie" kopiowanie
  141.      * samych adresów.
  142.      * Dzięki gwiazdkom, wywołujemy operator= rekurencyjnie dla kolejnych
  143.      * elementów listy
  144.      */
  145.  
  146.     *Nastepny = *oryginal.Nastepny; /* "niewidzialna" rekurencja */
  147.  
  148.   } else {
  149.     /* Jeżeli nie ma więcej nic do kopiowania */
  150.     Nastepny = nullptr;
  151.   }
  152.  
  153.   ENDM( "Przypisanie" );
  154.   return *this; /* Żeby można było robić a = b = c */
  155. }
  156.  
  157. /* Destruktor */
  158. Wezel::~Wezel() {
  159.   BEGINM( "Destruktor" );
  160.   dump( "\t\t" );
  161.  
  162.   /* Ususwaj wszystko do końca listy */
  163.   if( Nastepny != nullptr ) delete Nastepny;
  164.   ENDM( "Destruktor" );
  165. }
  166.  
  167. /* Dopisanie elementu listy */
  168. Wezel& Wezel::operator<<( Wezel* nowy ) {
  169.   BEGINM( "Dopisanie" );
  170.   dump( "\t\t" );
  171.   if( Nastepny != nullptr ) delete Nastepny;
  172.  
  173.   Nastepny = nowy;
  174.   ENDM( "Dopisanie" );
  175.   return *nowy; /* Można zrobić l1 << new l2 << new l3; */
  176. }
  177.  
  178. /* Wypisanie listy  */
  179. void Wezel::wypisz() {
  180.   auto wskaznik = this; /* Zaczynamy od samego siebie */
  181.   cout << "\tLista:" << endl;
  182.  
  183.   /* Powtarzaj, dopóki nie dojdziesz do końca */
  184.   do {
  185.     wskaznik->dump( "\t\t" );
  186.     wskaznik = wskaznik->Nastepny;
  187.   } while( wskaznik != nullptr );
  188.  
  189.   cout << "\tKoniec listy" << endl << endl;
  190. }
  191.  
  192. /* Szukanie ostatniego */
  193. Wezel& Wezel::ostatni() {
  194.   if( Nastepny != nullptr )
  195.     /* Jeżeli jest jakiś następny, to może on jest ostatni? */
  196.     return Nastepny->ostatni();
  197.   else
  198.     /* Nie ma następnego, my jesteśmy ostatni */
  199.     return *this;
  200. }
  201.  
  202. /* ************************************************************************
  203.  * Tutaj zaczynają się funkcje, których działanie chcemy testować
  204.  * ************************************************************************/
  205.  
  206. void argument_kopia( Wezel arg ) {
  207.   BEGIN( "przez wartość" );
  208.   cout << "\t\tPrzed zmianą: ";
  209.   arg.wypisz();
  210.  
  211.   arg.ostatni() << new Wezel( "kopia" );
  212.  
  213.   cout << "\t\tPo zmianie: ";
  214.   arg.wypisz();
  215.  
  216.   END( "przez wartość" );
  217. }
  218.  
  219. void argument_referencja( Wezel& arg ) {
  220.   BEGIN( "przez referencję" );
  221.   cout << "\t\tPrzed zmianą: ";
  222.   arg.wypisz();
  223.  
  224.   arg.ostatni() << new Wezel( "referencja" );
  225.  
  226.   cout << "\t\tPo zmianie: ";
  227.   arg.wypisz();
  228.  
  229.   END( "przez referencję" );
  230. }
  231.  
  232. void argument_wskaznik( Wezel* arg ) {
  233.   BEGIN( "przez wskaźnik" );
  234.   cout << "\t\tPrzed zmianą: ";
  235.   arg->wypisz();
  236.  
  237.   arg->ostatni() << new Wezel( "Wskaznik" );
  238.  
  239.   cout << "\t\tPo zmianie: ";
  240.   arg->wypisz();
  241.  
  242.   END( "przez wskaźnik" );
  243. }
  244.  
  245. int main( int argc, char* argv[] ) {
  246.   BEGIN( "PROGRAM" );
  247.   cout << "************************************************" << endl;
  248.   cout << "Konstrukcja baza " << HERE << endl;
  249.   Wezel baza( "Bazowy" );
  250.  
  251.   cout << "************************************************" << endl;
  252.   cout << "Konstrukcja dodatkowych zmiennych " << HERE << endl;
  253.  
  254.   Wezel wart, ref, wsk;
  255.  
  256.   wart.wypisz();
  257.   ref.wypisz();
  258.   wsk.wypisz();
  259.  
  260.   cout << "************************************************" << endl;
  261.   cout << "Dołączenie nowych węzłów do baza " << HERE << endl;
  262.   baza << new Wezel( "nowy1" ) << new Wezel( "nowy2" );
  263.  
  264.   cout << "Po dopisaniu baza=";
  265.   baza.wypisz();
  266.  
  267.   cout << "************************************************" << endl;
  268.   cout << "Wywołanie funkcji 'przez wartość' " << HERE << endl;
  269.   cout << "Kopiowanie bazy" << endl;
  270.   wart = baza;
  271.   cout << "Przed wywołaniem=";
  272.   wart.wypisz();
  273.   cout << ">>> Wołanie funkcji" << endl;
  274.   argument_kopia( wart );
  275.   cout << "<<< po powrocie=";
  276.   wart.wypisz();
  277.  
  278.   cout << "************************************************" << endl;
  279.   cout << "Wywołanie funkcji 'przez referencję'" << HERE << endl;
  280.   cout << "Kopiowanie bazy" << endl;
  281.   ref = baza;
  282.   cout << "Przed wywołaniem=";
  283.   ref.wypisz();
  284.   cout << ">>> Wołanie funkcji" << endl;
  285.   argument_referencja( ref );
  286.   cout << "<<< po powrocie=";
  287.   ref.wypisz();
  288.  
  289.   cout << "************************************************" << endl;
  290.   cout << "Wywołanie funkcji 'przez wskaźnik'" << HERE << endl;
  291.   cout << "Kopiowanie bazy" << endl;
  292.   wsk = baza;
  293.   cout << "Przed wywołaniem=";
  294.   wsk.wypisz();
  295.   cout << ">>> Wołanie funkcji" << endl;
  296.   argument_wskaznik( &wsk );
  297.   cout << "<<< po powrocie=";
  298.   wsk.wypisz();
  299.  
  300.   cout << "************************************************" << endl;
  301.   cout << "Wywołanie funkcji 'przez wartość' dla obiektu tymczasowego " << HERE
  302.        << endl;
  303.   argument_kopia( Wezel( "Tymczasowy1" ) );
  304.  
  305.   cout << "************************************************" << endl;
  306.   END( "PROGRAM" );
  307.   return 0;
  308. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement