November 18, 2025, Tuesday, 321

Języki Programowania 7

From MJanik

(Difference between revisions)
Jump to: navigation, search
 
(9 intermediate revisions not shown)
Line 1: Line 1:
-
Grupa poniedziałek 14:00 - 16:00
+
[http://www.if.pw.edu.pl/~majanik/data/JP/2025/Zadanie7_baza_studentow.pdf Laboratorium 7] - Baza studentów, pola statyczne, konstruktor kopiujący, dynamiczna alokacja pamięci.
 +
<!--
-
[http://www.if.pw.edu.pl/~majanik/data/JP/2012/Zadanie7.Uczen.1.pdf Laboratorium 7 ]: klasa Uczen (operator =, new, delete, pierwszy Makefile)
+
Tematem zajęć będą pola statyczne, konstruktor kopiujący, dynamiczna alokacja pamięci.
 +
-->
-
Grupa wtorek 8:00 - 10:00
+
<hr/>
-
[http://www.if.pw.edu.pl/~majanik/data/JP/2012/Kolokwium_testowe.pdf Laboratorium 7 ]: klasa Owoc (tablica dynamiczna char*) oraz klasa Vector (pole statyczne i dodatki)
+
 
 +
Zadanie przykładowe:
 +
 
 +
 
 +
== Wprowadzenie: pola statyczne i metody statyczne ==
 +
 
 +
W języku C++ oprócz zwykłych pól i metod obiektowych możemy w klasie zdefiniować pola statyczne oraz metody statyczne. Są to elementy, które nie należą do konkretnego obiektu, lecz do samej klasy. Oznacza to, że:
 +
 
 +
* wszystkie obiekty danej klasy współdzielą jedną kopię pola statycznego,
 +
* pole statyczne istnieje, nawet jeśli nie utworzono jeszcze żadnego obiektu,
 +
* metodę statyczną można wywołać bez tworzenia obiektu, używając nazwy klasy.
 +
 
 +
Najczęstsze zastosowania pól statycznych to:
 +
* zliczanie liczby utworzonych obiektów,
 +
* przechowywanie ustawień wspólnych dla całej klasy,
 +
* przechowywanie wartości globalnych logicznie powiązanych z daną klasą.
 +
 
 +
Metody statyczne natomiast:
 +
* pozwalają wykonywać operacje związane z klasą jako całością (np. wypisywać stan pól statycznych),
 +
* nie mają dostępu do pól obiektów (bo nie działają na obiekcie),
 +
* mogą być wywoływane bez instancji.
 +
 
 +
W poniższym zadaniu te pojęcia zostaną wykorzystane do stworzenia klasy z polem statycznym, liczącym liczbę figur.
 +
 
 +
== Pole statyczne ==
 +
 +
'''Proszę napisać klasę figura posiadającą (oddzielne pliki .cpp i .h!):'''
 +
 
 +
- n - liczbę boków
 +
 
 +
- d - długość boku
 +
 
 +
- color - kolor (string)
 +
 
 +
- count - ilość figur - *static*!
 +
 
 +
 
 +
metody:
 +
 
 +
- konstruktor. Domyślnym kolorem jest czerwony, a domyślna liczba boków to 3. Stworzenie nowej figury powinno zwiększać pole count o 1.
 +
 
 +
- ZmienKolor(string new_color);
 +
 
 +
- ZmienLiczbeBokow(int new_b);
 +
 
 +
oraz metodę statyczną wypisującą ilość figur (count) - [static void wypisz_count()]
 +
 
 +
 
 +
=== Zadania w funkcji main ===
 +
 
 +
'''1. Na początku programu:'''
 +
 
 +
Wywołać metodę statyczną wypisz_count() bez tworzenia żadnego obiektu.
 +
 
 +
'''2. Utworzyć trzy obiekty klasy figura:'''
 +
 
 +
figura f1(4, "zielona");
 +
 
 +
figura f2(8, "niebieska");
 +
 
 +
figura f3;
 +
 
 +
Następnie ponownie wywołać wypisz_count().
 +
 
 +
'''3. Stworzyć tablicę figur:'''
 +
 
 +
figura * fig_tab;
 +
 
 +
dla 5 nowych figur (stworzyć tablicę dynamicznie używając new).
 +
 
 +
Następnie wywołać wypisz_count(), aby wypisać aktualną liczbę figur.
 +
 +
'''Jak działa pole statyczne? Jaką zaletę ma funkcja statyczna?'''
 +
 
 +
 
 +
 
 +
== Konstruktor kopiujący ==
 +
Konstruktor kopiujący to specjalny konstruktor w C++, który służy do tworzenia nowego obiektu na podstawie już istniejącego obiektu tej samej klasy.
 +
 
 +
Jego ogólna postać:
 +
 
 +
  ClassName(const ClassName& other);
 +
 
 +
Szczególnie ważny jest w klasach, które zarządzają zasobami, takimi jak:
 +
* pamięć dynamiczna (new/delete),
 +
* uchwyty do plików,
 +
* połączenia sieciowe,
 +
* wskaźniki na tablice, struktury itp.
 +
 
 +
Domyślny konstruktor kopiujący wykonuje płytką kopię (shallow copy):
 +
* kopiuje wartości pól bit po bicie,
 +
co oznacza, że wskaźniki będą wskazywać na tę samą pamięć.
 +
 
 +
 
 +
'''Zadanie do przećwiczenia'''
 +
 
 +
'Należy zdefiniować klasę człowiek:
 +
class czlowiek{
 +
char *imie; //skladniki klasy to wskazniki, NIE tablice
 +
char *nazwisko; //kopiujac skladnik po skladniku robimy wierne kopie wskaznikow
 +
public:         //pokazujacych na to samo miejsce w pamieci
 +
czlowiek();
 +
czlowiek(char*, char*);
 +
czlowiek(const czlowiek &);
 +
~czlowiek();
 +
void wypiszCzlowieka();
 +
void zmienNazwisko(char*);
 +
};
 +
 
 +
Oraz wypełnić odpowiednie funkcje składowe (konstruktory oraz funkcje wypiszCzlowieka i zmienNaziwsko).
 +
 
 +
Uwaga - w ramach ćwiczenia zarządzania pamięcią dynamiczną spróbuj przygotować tak program, żeby tablice imie i nazwisko zawsze były alokowane na odpowiednią ilość liter (długość imienia/nazwiska +1). Czyli funkcja zmienNazwisko powinna usuwać poprzednio przydzieloną pamięć i alokować ją na nowo na odpowiednią długość. Możesz użyć funkcji strlen żeby ocenić jak długa powinna być tablica.
 +
 
 +
 +
A następnie wykonać program:
 +
 
 +
int main() {
 +
char i[4]= "Jan";
 +
char n[9]= "Kowalski";
 +
char r[6]= "Nowak";
 +
czlowiek c1(i, n);
 +
czlowiek c2(c1);
 +
c1.przedstaw();
 +
c2.przedstaw();
 +
c1.zmiana(r);
 +
c1.przedstaw();
 +
c2.przedstaw();
 +
return 1;
 +
}
 +
 
 +
 
 +
Jaki byłby wynik, gdybyśmy nie zdefiniowali konstruktora kopiującego? (Proszę sprawdzić, komentując odpowiedni kawałek kodu!).

Latest revision as of 08:37, 14 November 2025

Laboratorium 7 - Baza studentów, pola statyczne, konstruktor kopiujący, dynamiczna alokacja pamięci.



Zadanie przykładowe:


Contents

Wprowadzenie: pola statyczne i metody statyczne

W języku C++ oprócz zwykłych pól i metod obiektowych możemy w klasie zdefiniować pola statyczne oraz metody statyczne. Są to elementy, które nie należą do konkretnego obiektu, lecz do samej klasy. Oznacza to, że:

  • wszystkie obiekty danej klasy współdzielą jedną kopię pola statycznego,
  • pole statyczne istnieje, nawet jeśli nie utworzono jeszcze żadnego obiektu,
  • metodę statyczną można wywołać bez tworzenia obiektu, używając nazwy klasy.

Najczęstsze zastosowania pól statycznych to:

  • zliczanie liczby utworzonych obiektów,
  • przechowywanie ustawień wspólnych dla całej klasy,
  • przechowywanie wartości globalnych logicznie powiązanych z daną klasą.

Metody statyczne natomiast:

  • pozwalają wykonywać operacje związane z klasą jako całością (np. wypisywać stan pól statycznych),
  • nie mają dostępu do pól obiektów (bo nie działają na obiekcie),
  • mogą być wywoływane bez instancji.

W poniższym zadaniu te pojęcia zostaną wykorzystane do stworzenia klasy z polem statycznym, liczącym liczbę figur.

Pole statyczne

Proszę napisać klasę figura posiadającą (oddzielne pliki .cpp i .h!):

- n - liczbę boków

- d - długość boku

- color - kolor (string)

- count - ilość figur - *static*!


metody:

- konstruktor. Domyślnym kolorem jest czerwony, a domyślna liczba boków to 3. Stworzenie nowej figury powinno zwiększać pole count o 1.

- ZmienKolor(string new_color);

- ZmienLiczbeBokow(int new_b);

oraz metodę statyczną wypisującą ilość figur (count) - [static void wypisz_count()]


Zadania w funkcji main

1. Na początku programu:

Wywołać metodę statyczną wypisz_count() bez tworzenia żadnego obiektu.

2. Utworzyć trzy obiekty klasy figura:

figura f1(4, "zielona");

figura f2(8, "niebieska");

figura f3;

Następnie ponownie wywołać wypisz_count().

3. Stworzyć tablicę figur:

figura * fig_tab;

dla 5 nowych figur (stworzyć tablicę dynamicznie używając new).

Następnie wywołać wypisz_count(), aby wypisać aktualną liczbę figur.

Jak działa pole statyczne? Jaką zaletę ma funkcja statyczna?


Konstruktor kopiujący

Konstruktor kopiujący to specjalny konstruktor w C++, który służy do tworzenia nowego obiektu na podstawie już istniejącego obiektu tej samej klasy.

Jego ogólna postać:

 ClassName(const ClassName& other);

Szczególnie ważny jest w klasach, które zarządzają zasobami, takimi jak:

  • pamięć dynamiczna (new/delete),
  • uchwyty do plików,
  • połączenia sieciowe,
  • wskaźniki na tablice, struktury itp.

Domyślny konstruktor kopiujący wykonuje płytką kopię (shallow copy):

  • kopiuje wartości pól bit po bicie,

co oznacza, że wskaźniki będą wskazywać na tę samą pamięć.


Zadanie do przećwiczenia

'Należy zdefiniować klasę człowiek:

class czlowiek{
char *imie; //skladniki klasy to wskazniki, NIE tablice
char *nazwisko; //kopiujac skladnik po skladniku robimy wierne kopie wskaznikow
public:         //pokazujacych na to samo miejsce w pamieci
czlowiek();
czlowiek(char*, char*);
czlowiek(const czlowiek &);
~czlowiek();
void wypiszCzlowieka();
void zmienNazwisko(char*);
};

Oraz wypełnić odpowiednie funkcje składowe (konstruktory oraz funkcje wypiszCzlowieka i zmienNaziwsko).

Uwaga - w ramach ćwiczenia zarządzania pamięcią dynamiczną spróbuj przygotować tak program, żeby tablice imie i nazwisko zawsze były alokowane na odpowiednią ilość liter (długość imienia/nazwiska +1). Czyli funkcja zmienNazwisko powinna usuwać poprzednio przydzieloną pamięć i alokować ją na nowo na odpowiednią długość. Możesz użyć funkcji strlen żeby ocenić jak długa powinna być tablica.


A następnie wykonać program:

int main() {
char i[4]= "Jan";
char n[9]= "Kowalski";
char r[6]= "Nowak";
czlowiek c1(i, n);
czlowiek c2(c1);
c1.przedstaw();
c2.przedstaw();
c1.zmiana(r);
c1.przedstaw();
c2.przedstaw();
return 1;
}


Jaki byłby wynik, gdybyśmy nie zdefiniowali konstruktora kopiującego? (Proszę sprawdzić, komentując odpowiedni kawałek kodu!).