Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
Nowa wersja
Poprzednia wersja
pl:dydaktyka:jimp2:2017:labs:klasy2 [2017/03/28 10:20]
kkutt [Co jest tymi zasobami?]
pl:dydaktyka:jimp2:2017:labs:klasy2 [2019/06/27 15:50] (aktualna)
Linia 1: Linia 1:
 ====== Klasy i obiekty II ====== ====== Klasy i obiekty II ======
  
-===== Zasady ​żądzące życiem obiektu =====+===== Zasady ​rządzące życiem obiektu =====
  
 Zapoznać się z regułami przedstawionymi w dokumentacji na stacku Zapoznać się z regułami przedstawionymi w dokumentacji na stacku
-[[http://stackoverflow.com/documentation/c%2b%2b/​1206/​the-rule-of-three-five-and-zero#​t=201703272317519853522|Zasada zera, zasada pięciu, zasada trzech]].+[[http://www.riptutorial.com/cplusplus/topic/​1206/​the-rule-of-three--five--and-zero|Zasada zera, zasada pięciu, zasada trzech]].
  
  
 <file cpp XXX.h> <file cpp XXX.h>
 +#include <​string>​
 +#include <​cstring>​
 +#include <​algorithm>​
 +using ::​std::​swap;​
 +
 class XXX { class XXX {
 +public:
   //w zeszłym odcinku:   //w zeszłym odcinku:
   //domyślny konstruktor   //domyślny konstruktor
Linia 27: Linia 33:
   //5. Destruktor   //5. Destruktor
   ~XXX();   ~XXX();
-}+};
 </​file>​ </​file>​
  
Linia 51: Linia 57:
   //tutaj przypisujemy stan obiektu jednego do drugiego   //tutaj przypisujemy stan obiektu jednego do drugiego
   //ale obydwa są już zaincjalizowane...   //ale obydwa są już zaincjalizowane...
-  ​XXX another_xxx = new_xxx;+  another_xxx = new_xxx;
   ​   ​
   //tutaj kończy się zakres funkcji main i wszystkie trzy obiekty tracą ważność   //tutaj kończy się zakres funkcji main i wszystkie trzy obiekty tracą ważność
Linia 69: Linia 75:
 } }
  
-int movement_example() {+int main() {
   //​Konstrukcja obiektu za pomocą domyślnego konstruktora   //​Konstrukcja obiektu za pomocą domyślnego konstruktora
   //​nieciekawe   //​nieciekawe
Linia 84: Linia 90:
   //ale obydwa są już zaincjalizowane...   //ale obydwa są już zaincjalizowane...
   //stan new_xxx teraz będzie w another_xxx,​ a sam new_xxx jest niszczony   //stan new_xxx teraz będzie w another_xxx,​ a sam new_xxx jest niszczony
-  ​XXX another_xxx = move(new_xxx);​+  another_xxx = std::move(new_xxx);​
   ​   ​
   //tutaj zostanie wywoały konstruktor kopiujący (argument wysyłany przez wartość)   //tutaj zostanie wywoały konstruktor kopiujący (argument wysyłany przez wartość)
Linia 109: Linia 115:
 <file cpp XXX.h> <file cpp XXX.h>
 class XXX { class XXX {
-  X() : name_{new char[1024]} { 
-  ​ 
-  } 
  ​private:​  ​private:​
   char *name_;   char *name_;
 }; };
 +</​file>​
 +<file cpp XXX.cpp>
 +XXX::XXX() : name_{new char[1024]} {
 +  ​
 +}
 </​file>​ </​file>​
  
 Brak destruktora powoduje wyciek pamięci, która nigdy nie jest zwalniana: Brak destruktora powoduje wyciek pamięci, która nigdy nie jest zwalniana:
 <file cpp XXX.cpp> <file cpp XXX.cpp>
-class XXX { +//5. destruktor:​ 
-  //... +XXX::~XXX() { 
-  ​//5. destruktor:​ +  delete [] name_; 
-  ~XXX() { +}
-    delete [] name_; +
-  }+
 </​file>​ </​file>​
  
Linia 140: Linia 146:
 Więc: Więc:
 <file cpp XXX.cpp> <file cpp XXX.cpp>
-class XXX { +//​konstruktor kopiujący:​ 
-  //... +XXX::XXX(const XXX& xxx) {
-  ​//​konstruktor kopiujący:​ +
-  XXX(const XXX& xxx) {+
     size_t sz = strlen(xxx.name_);​     size_t sz = strlen(xxx.name_);​
     name_ = new char[sz];     name_ = new char[sz];
-    strcpy(name_,​xxx.name);+    strcpy(name_,​xxx.name_);
     //Teraz nowy obiekt pokazuje na nowy fragment pamięci, ​     //Teraz nowy obiekt pokazuje na nowy fragment pamięci, ​
     //ale ze skopiowaną informacją     //ale ze skopiowaną informacją
   }   }
   //operator przypisania:​   //operator przypisania:​
-  ​XXX & operator=(const XXX& xxx) { +XXX & XXX::operator=(const XXX& xxx) { 
-    //jeśli ktoś wpadł na pomsył x = x;+    //jeśli ktoś wpadł na pomysł x = x;
     if (this == &xxx) {     if (this == &xxx) {
-      return ​xxx;+      return ​*this;
     }     }
     //w przyciwynym wypadku mamy x = y;     //w przyciwynym wypadku mamy x = y;
Linia 161: Linia 165:
     //i wreszcie kopiowanie, ten kod jest     //i wreszcie kopiowanie, ten kod jest
     //jest identyczny więc można by go wydzielić do innej metody...     //jest identyczny więc można by go wydzielić do innej metody...
-    size_t sz = strlen(xxx.name); +    size_t sz = strlen(xxx.name_); 
-    ​name = new char[sz]; +    ​name_ = new char[sz]; 
-    strcpy(name,xxx.name);+    strcpy(name_,xxx.name_);
   }   }
 </​file>​ </​file>​
Linia 170: Linia 174:
  
 <file cpp XXX.cpp> <file cpp XXX.cpp>
-class XXX { 
-  //... 
   //​konstruktor przenoszący:​   //​konstruktor przenoszący:​
-  ​XXX(XXX &&​xxx) : name_{nullptr} {+XXX::XXX(XXX &&​xxx) : name_{nullptr} {
     swap(name_,​xxx.name_);​     swap(name_,​xxx.name_);​
     //Bardzo popularna szutczka     //Bardzo popularna szutczka
Linia 181: Linia 183:
     //delete nullptr jest bezpieczna operacją i nic się nie stanie...     //delete nullptr jest bezpieczna operacją i nic się nie stanie...
   }   }
-  ​//operator przenoszący:​ + 
-  XXX & operator=(XXX &&​xxx) {+//operator przenoszący:​ 
 +XXX & XXX::operator=(XXX &&​xxx) {
     //jeśli ktoś wpadł na pomsył x = move(x);     //jeśli ktoś wpadł na pomsył x = move(x);
     if (this == &xxx) {     if (this == &xxx) {
Linia 350: Linia 353:
     * Pliki z implementacją:​ **MemoryChunk.h/​cpp**     * Pliki z implementacją:​ **MemoryChunk.h/​cpp**
     * Używana struktura danych: **MemoryChunk**     * Używana struktura danych: **MemoryChunk**
-    * Sygnatury metod w klasie ​SimpleUrl: <code cpp> ​ Rule of Five+    * Sygnatury metod w klasie ​MemoryChunk: <code cpp> ​ Rule of Five
   MemoryChunk(size_t sz);   MemoryChunk(size_t sz);
   int8_t *MemoryAt(size_t offset) const;   int8_t *MemoryAt(size_t offset) const;
   size_t ChunkSize() const;</​code>​   size_t ChunkSize() const;</​code>​
-    * Przestrzeń nazw: **memory**+    * Przestrzeń nazw: **memorychunk**
     * Importy: <code cpp>#​include <​cstdint>​     * Importy: <code cpp>#​include <​cstdint>​
 #include <​algorithm></​code>​ #include <​algorithm></​code>​
     * Przydatne metody: <code cpp>​std::​copy(from,​from+size,​to);​     * Przydatne metody: <code cpp>​std::​copy(from,​from+size,​to);​
 </​code>​ </​code>​
-  - **[2 punkty] Pula łańcuchów znaków jest to jeden ze sposobów optymalizacji dużej ilości napisów w programie. Trick polega na tym, że powtarzające się napisy ​przechwujemy ​w tym samym miejscu pamięci. Niestety klasa string ​się nie nadaje do naszych celów, ​gdyż pozwalałaby na modyfikowanie napisówprzechowywanych w strukturze (jeśli kilka napisów wskazuje na ten sam obszar pamięci to byłoby straszne). W C%%++%%17 wchodzi typ string_view czyli niezmienny napis, który dodatkowo posiada metodę substr działającą w czasie stałym!**+  - **[2 punkty] Pula łańcuchów znaków jest to jeden ze sposobów optymalizacji dużej ilości napisów w programie. Trick polega na tym, że powtarzające się napisy ​przechowujemy ​w tym samym miejscu pamięci. Obiektowi puli napisów można powierzyć przechowywanie konkretnego napisu za pomocą funkcji Intern w rezultacie dostajemy uchwyt do napisu, który jest już zarządzany przez obiekt puli. Jeśli kilka identycznych napisów zostanie wstawionych do puli to tylko jedna instancja napisu będzie przechowywana wewnątrz, a wszystkie zwracany uchwyty pokazują ciągle na ten sam napis wewnątrz puli. Niestety klasa string nie nadaje ​się do naszych celów ​zwracania uchwytu napisuponieważ to ona sama zarządza pamięcią i wymaga kopiowania napisu a ponadto ​pozwalałaby na modyfikowanie napisów przechowywanych w strukturze (jeśli kilka napisów wskazuje na ten sam obszar pamięci to byłoby straszne). W C%%++%%17 wchodzi typ string_view czyli niezmienny napis, który dodatkowo posiada metodę substr działającą w czasie stałym! ​Twoim zadaniem jest przygotowanie implementacji takie puli napisów.**
     * Moduł: **textpool**     * Moduł: **textpool**
     * Pliki z implementacją:​ **TextPool.h/​cpp**     * Pliki z implementacją:​ **TextPool.h/​cpp**
Linia 373: Linia 376:
 #include <​experimental/​string_view>​ #include <​experimental/​string_view>​
 #include <​set></​code>​ #include <​set></​code>​
 +    * Przykład użycia: <code cpp>#​include <​iostream>​
 +#include "​TextPool.h"​
 +
 +using namespace pool;
 +using namespace std;
 +
 +int main() {
 +  //​Inicjalizacja wstępna puli za pomocą listy inicjalizacyjnej
 +  TextPool pool {"​abc",​ "​efg",​ "​hij",​ "​klmn",​ "​oprst"​};​
 +
 +  //​wstawienie napisu do puli
 +  auto s1 = pool.Intern("​efg"​);​
 +
 +  //​wstawienie kolejnego napisu do puli (w obu przypadkach nie
 +  //powinien się zmienić rozmiar puli)
 +  auto s2 = pool.Intern("​efg"​);​
 +
 +  cout << (s1 == s2 ? "​True"​ : "​False"​) << endl; //uchwyty są tymi samymi napisami co do wartości
 +  cout << pool.StoredStringCount() << endl; // w puli jest wciąż 5 napisów
 +  cout << (s1.begin() == s2.begin() ? "​True"​ : "​False"​) << endl; //na dodatek uchywyty s1 i s2 pokazują dokładnie na ten sam napis w puli (wskaźniki są identyczne)
 +}</​code>​
   - [1 plus] Napisz dwie klasy: Rodzic i Dziecko. Klasa Rodzic powinna mieć takie pola jak imię, nazwisko, wiek, oraz dziecko (zakładamy dla uproszczenia,​ że rodzic ma tylko jedno dziecko :) ). Dziecko powinno mieć takie pola jak imię, nazwisko, wiek, szkoła. Zdefiniuj klasę Rodzic jako zaprzyjaźnioną klasy Dziecko. Przetestuj, czy można modyfikować zmienne prywatne klasy Dziecko z poziomu metod klasy Rodzic. Napisz na przykład metodę //​przepiszDoInnejSzkoly(string nazwa)// która będzie zmieniać szkołę dziecka operując bezpośrednio na jego danych. \\ Następnie usuń linijkę odpowiedzialną za określenie klasy zaprzyjaźnionej i spróbuj skompilować ponownie program.   - [1 plus] Napisz dwie klasy: Rodzic i Dziecko. Klasa Rodzic powinna mieć takie pola jak imię, nazwisko, wiek, oraz dziecko (zakładamy dla uproszczenia,​ że rodzic ma tylko jedno dziecko :) ). Dziecko powinno mieć takie pola jak imię, nazwisko, wiek, szkoła. Zdefiniuj klasę Rodzic jako zaprzyjaźnioną klasy Dziecko. Przetestuj, czy można modyfikować zmienne prywatne klasy Dziecko z poziomu metod klasy Rodzic. Napisz na przykład metodę //​przepiszDoInnejSzkoly(string nazwa)// która będzie zmieniać szkołę dziecka operując bezpośrednio na jego danych. \\ Następnie usuń linijkę odpowiedzialną za określenie klasy zaprzyjaźnionej i spróbuj skompilować ponownie program.
   - [3 plusy] Napisz klasę Marsjanin, która będzie miała statyczne pole //​liczbaMarsjan//,​ określające liczbę stworzonych obiektów Marsjanin. Każdy Marsjanin powinien atakować gdy liczba wszystkich Marsjan jest większa od 5 i ukrywać się w przeciwnym wypadku. \\ Napisz program który w pętli nieskończonej będzie tworzył lub usuwał obiekty klasy Marsjanin i wywoływał metodę //atakuj// dla wszystkich Marsjan. Obiekty powinny być przechowywane w liście (zobacz [[http://​www.cplusplus.com/​reference/​stl/​list/​|List]]).   - [3 plusy] Napisz klasę Marsjanin, która będzie miała statyczne pole //​liczbaMarsjan//,​ określające liczbę stworzonych obiektów Marsjanin. Każdy Marsjanin powinien atakować gdy liczba wszystkich Marsjan jest większa od 5 i ukrywać się w przeciwnym wypadku. \\ Napisz program który w pętli nieskończonej będzie tworzył lub usuwał obiekty klasy Marsjanin i wywoływał metodę //atakuj// dla wszystkich Marsjan. Obiekty powinny być przechowywane w liście (zobacz [[http://​www.cplusplus.com/​reference/​stl/​list/​|List]]).
   - **[3 punkty] Zaimplementuj klasę o nazwie Matrix, która będzie reprezentować macierz o dowolnych rozmiarach. Wymagania dotyczące klasy Matrix:**   - **[3 punkty] Zaimplementuj klasę o nazwie Matrix, która będzie reprezentować macierz o dowolnych rozmiarach. Wymagania dotyczące klasy Matrix:**
 +    * Moduł: **matrix**
 +    * Pliki z implementacją:​ **Matrix.h/​cpp**
 +    * Używana struktura danych: **Matrix**
   * Klasa powinna wewnętrznie reprezentować macierz przy pomocy tablicy dwuwymiarowej obiektów typu std::​complex<​double>​. Umawiamy się, że liczba zespolona zapisywana jest w następujący sposób: <​code>​4.5i6</​code>​ Co oznacza w zapisie matematycznym <​code>​4.5 + 6i</​code>​   * Klasa powinna wewnętrznie reprezentować macierz przy pomocy tablicy dwuwymiarowej obiektów typu std::​complex<​double>​. Umawiamy się, że liczba zespolona zapisywana jest w następujący sposób: <​code>​4.5i6</​code>​ Co oznacza w zapisie matematycznym <​code>​4.5 + 6i</​code>​
   * Klasa Matrix powinna posiadać konstruktor parometrowy określający jej wymiary, konstruktor bezparametrowy,​ oraz kopiujący. Dopisać konstruktor,​ który będzie przyjmować napis //const char*// (lub obiekt klasy string z biblioteki //​string.h//​) w notacji Matlaba i parsować go, aby można było stworzyć obiekt Matrix w taki sposób: <code cpp> Matrix m("​[1i3 2i5 3; 3 4 5; 6 7 8]"​);</​code> ​   * Klasa Matrix powinna posiadać konstruktor parometrowy określający jej wymiary, konstruktor bezparametrowy,​ oraz kopiujący. Dopisać konstruktor,​ który będzie przyjmować napis //const char*// (lub obiekt klasy string z biblioteki //​string.h//​) w notacji Matlaba i parsować go, aby można było stworzyć obiekt Matrix w taki sposób: <code cpp> Matrix m("​[1i3 2i5 3; 3 4 5; 6 7 8]"​);</​code> ​
Linia 411: Linia 438:
  
 <WRAP center round info 60%> <WRAP center round info 60%>
-Zabezpieczenie programu przed sytuacjami wyjątkowymi w "​podstawowej"​ wersji, wymaganej na laboratorium,​ związane jest ze sprawdzeniem odpowiedniej wartości i wypisaniem komunikatu dla użytkownika. Bardziej profesjonalny sposób obsługi takich sytuacji związany jest z **mechanizmem wyjątków**. ​Jeżeli chcesz dowiedzieć się o nim czegoś więcej, zapraszam do zapoznania ​się z nieobowiązkową instrukcją do laboratorium [[.:​wyjatki|Wyjątki]].+Zabezpieczenie programu przed sytuacjami wyjątkowymi w "​podstawowej"​ wersji, wymaganej na laboratorium,​ związane jest ze sprawdzeniem odpowiedniej wartości i wypisaniem komunikatu dla użytkownika. Bardziej profesjonalny sposób obsługi takich sytuacji związany jest z **mechanizmem wyjątków**. ​Więcej nich dowiemy ​się na laboratorium [[.:​wyjatki|Wyjątki]].
 </​WRAP>​ </​WRAP>​
  
  
pl/dydaktyka/jimp2/2017/labs/klasy2.1490689241.txt.gz · ostatnio zmienione: 2019/06/27 15:52 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0