Kategorie materiałów Informatyka

Przedmiot: C++ Dla Zaawansowanych Wróć do kategorii

LEKCJA 30. Wymiana danych między obiektami

plik Pobierz LEKCJA 30. Wymiana danych miedzy obiektami.txt

LEKCJA 30: WYMIANA DANYCH MIĘDZY OBIEKTAMI. 
________________________________________________________________
 
W trakcie tej lekcji dowiesz się, jak można wymieniać dane i 
informacje pomiędzy różnymi obiektami. 
________________________________________________________________
 
 
Hermetyzacja danych jest cenną zdobyczą, ale od czasu do czasu 
obiekty powinny dokonywać pomiędzy sobą wymiany informacji, 
także tych wewnętrznych - prywatnych. Ten problem może sprawiać 
programiście trochę kłopotów - należy zatem poświęcić mu trochę 
uwagi. 
 
DOSTĘP DO DANYCH PRZY POMOCY FUNKCJI KATEGORII friend. 
 
Aby wyjaśnić mechanizmy dostępu do danych obiektów będziemy 
potrzebować: 
 
* wielu obiektów; 
* danych prywatnych obiektów (dostęp do publicznych, 
"niezakapsułkowanych" danych jest prosty i oczywisty); 
* funkcji o specjalnych uprawnieniach.
 
Takie funkcje o specjalnych uprawnieniach - z możliwością 
odwoływania się do prywatnych danych wielu obiektów (a nie tylko
 
swojego) muszą w C++ posiadać status "friend" (ang. friend - 
przyjaciel). 
 
Nasz przykładowy program będzie operował tablicą złożoną z 
obiektów klasy Licznik. 
 
class Licznik

  char moja_litera; 
  int ile;
public: 
  void Inicjuj_licznik(char); 
  void Skok_licznika(void); 
  void Pokazuj();
}; 
 
 ... 
Licznik TAB[MAX];
 
Obiekty - liczniki będą zliczać wystąpienie (każdy swojego) 
określonego znaku w strumieniu znaków wejściowych (wczytywanym z
 
klawiatury). Tablica będzie się składać z MAX == 26 elementów - 
obiektów - liczników, po jednym dla każdej dużej litery 
alfabetu. Tablica będzie nazywać się TAB[26]. Po zadeklarowaniu:
 
 
nazwa_klasy TAB[MAX]; 
 
kolejne obiekty będą się nazywać: 
 
nazwa_klasy Obiekt1 == TAB[0];       //Licznik 1 - 'A'
nazwa_klasy Obiekt2 == TAB[1];       //Licznik 2 - 'B'
 ...                                    ...
nazwa_klasy ObiektN == TAB[N-1]; 
 
Po wprowadzeniu znaku z klawiatury wywołamy wbudowaną do każdego
 
obiektu funkcję Skok_licznika(), która doda jedynkę do 
wewnętrznego licznika obiektu. Wywołując funkcję zastosujemy 
zamiast typowej składni 
 
ObiektK.Skok_licznika(); 
 
odpowiadającą jej w tym wypadku notację 
 
TAB[i].Skok_licznika();
 
Powinniśmy jeszcze przed wywołaniem funkcji sprawdzić, czy znak 
jest dużą literą alfabetu. W przykładowym programie zrobimy to 
tak: 
 
 ...
  cin >> znak;                     //Pobranie znaku z klawiatury
  for(int i = 0; i < 26; i++)
     { 
       if(i == (znak - 'A')) TAB[i].Skok_licznika(); 
     }
 ...
 
Dzięki temu wewnętrzny licznik obiektu TAB[2] zostanie 
powiększony tylko wtedy, gdy znak - 'A' == 2 (znak jest literą 
C, bo 'C' - 'A' == 2). 
 
Można to zapisać skuteczniej.
...
   cin >> znak;
   TAB[znak - 'A'].Skok_licznika();    //Inkrementacja licznika 
 ...
 
bądź jeszcze krócej: 
 
 ...
   TAB[getch() - 'A'].Skok_licznika(); 
 ...
 
Istnieje tu wszakże niebezpieczeństwo próby odwołania się do 
nieistniejącego elementu tablicy, przed czym powinniśmy się 
wystrzegać.
 
W wyniku działania programu otrzymamy zliczoną ilość 
występowania danej litery w strumieniu znaków wejściowych. 
 
[P107.CPP] 
 
# include <ctype.h>            //prototyp toupper() 
# include <iostream.h>  
 
class Licznik 
{  
  char moja_litera;  
  int ile; 
public:  
  void Inicjuj(char);  
  void Skok_licznika();  
  void Pokazuj(); 
};  
 
void Licznik::Inicjuj(char z)  
{  
  moja_litera = z;  
  ile = 0;  
}  
 
void Licznik::Skok_licznika(void)  
{  
  ile++;  
}  
 
void Licznik::Pokazuj(void)  
{  
  cout << "Znak " << moja_litera << " wystapil "  
       << ile << " razy" << '\n';  

main()  
{  
const MAX = 26;
Licznik TAB[MAX];  
register int i;  
 
/* inicjujemy liczniki:  -------------------------------*/  
 
for(i = 0; i < MAX; i++)  
   {  
     TAB[i].Inicjuj('A' + i);  
   } 
/* pracujemy - zliczamy: -------------------------------*/ 
 
cout << "Wpisz ciag zankow zakonczony kropka [.]" << '\n'; 
for(;;)  
  { char znak; 
    cin >> znak; 
    if(znak == '.') break; 
    for(i = 0; i < MAX; i++)  
       {  
         if(i == (znak - 'A')) TAB[i].Skok_licznika();  
       }  
  } 
/* sprawdzamy: ----------------------------------------*/ 
 
char sprawdzamy; 
cout << '\n' << "Podaj znak do sprawdzenia: " << '\n';  
cin >> sprawdzamy; 
cout << "Wyswietlam wyniki zliczania: \n";  
  TAB[toupper(sprawdzamy) - 'A'].Pokazuj();  
 
return 0;  

 
Jeśli chcielibyśmy zliczyć ilość wszystkich wprowadzonych 
znaków, powinniśmy zsumować dane pobrane od wielu obiektów. 
 
Jeśli dane przechowywane w obiektach mają status danych 
prywatnych, to dostęp do tych danych może być utrudniony. Do 
tego momentu dostęp do danych prywatnych obiektu mogliśmy 
uzyskać tylko posługując się autoryzowaną do tego metodą - 
własną funkcją wewnętrzną tegoż obiektu. Ale wtedy nie mieliśmy 
dostępu do danych innych obiektów a tylko do jednego - 
"własnego" obiektu funkcji. Jeśli zatem chcielibyśmy zsumować 
zawartości wielu obiektów - liczników, to należy do tego 
zastosować tzw. funkcję "zaprzyjaźnioną" - friend function. 
Jeśli deklarując funkcję zastosujemy słowo kluczowe friend, to 
taka zaprzyjaźniona z klasą funkcja uzyska prawo dostępu do 
prywatnych elementów danej klasy. Zadeklarujemy taką przykładową
 
zaprzyjaźnioną funkcję o nazwie Suma(). Funkcja będzie pobierać 
jako parametr ilość obiektów do zsumowania i sumować zawartości 
wewnętrznych liczników obiektów. 
 
const MAX = 26;
 
class Licznik 
{  
  char moja_litera;  
  int ile; 
public:  
  void Inicjuj(char);  
  void Skok_licznika();  
  void Pokazuj(); 
  friend int Suma(int); 
} TAB[MAX];
 
Zadeklarowana w taki sposób zaprzyjażniona funkcja ma prawo 
dostępu do prywatnych elementów wszystkich obiektów klasy 
Licznik. Typowe zastosowanie funkcji typu friend polega właśnie 
na dostępie do danych wielu różnych obiektów. Powinniśmy 
zsumować zawartość pól 
 
TAB[i].ile 
 
dla wszystkich obiektów (od i = 0 aż do i = MAX). Zwróć uwagę, 
że definiując funkcję Suma() nie stosujemy powtórnie słowa 
kluczowego friend. A oto definicja: 
 
int Suma(int ilosc_obiektow) 

      int i, suma = 0; 
   for(i = 0; i < ilosc_obiektow; i++) 
      suma += TAB[i].ile; 
 
      return (suma); 

 
Dzięki zastosowaniu słowa "friend", funkcja Suma() jest 
zaprzyjaźniona ze wszystkimi 26 obiektami, ponieważ wszystkie 
obiekty należą do tej klasy, w której zadeklarowaliśmy funkcję:
 
class ... 

 ...
friend int Suma(...); 
 ... 
} ... ; 
 
Tablica TAB[MAX] złożona z obiektów klasy Licznik została 
zadeklarowana nazewnątrz funkcji main() ma więc status tablicy 
GLOBALNEJ. Funkcja Suma() ma dostęp do prywatnych danych 
wszystkich obiektów, możemy więc zastosować ją w programie w 
następujący sposób:
 
[P108.CPP]
 
# include <ctype.h>
# include <iostream.h> 
 
class Licznik 
{  
  char moja_litera;  
  int ile; 
public:  
  void Inicjuj(char);  
  void Skok_licznika();  
  void Pokazuj(); 
  friend int Suma(int); 

const MAX = 26;
Licznik TAB[MAX];
register int i;  
 
main()  
{  
/* inicjujemy liczniki: -------------------------------*/ 
 
for(i = 0; i < MAX; i++)  
   {  
     TAB[i].Inicjuj('A' + i);  
   } 
/* pracujemy - zliczamy: -------------------------------*/ 
 
cout << "Wpisz ciag zankow zakonczony kropka [.]" << '\n'; 
for(;;)  
  { char znak; 
    cin >> znak; 
    if(znak == '.') break; 
    for(i = 0; i < MAX; i++)  
       {  
         if(i == (znak - 'A')) TAB[i].Skok_licznika();  
       }  
  } 
/* sprawdzamy: ----------------------------------------*/ 
 
char sprawdzamy; 
cout << '\n' << "Podaj znak do sprawdzenia: " << '\n';  
cin >> sprawdzamy; 
cout << "Wyswietlam wyniki zliczania: \n";  
  TAB[toupper(sprawdzamy) - 'A'].Pokazuj();  
 
cout << "\n Wszystkich liter bylo " << Suma(MAX);
 
return 0;  

 
void Licznik::Inicjuj(char zn)  
{  
  moja_litera = zn;  
  ile = 0;  
}  
 
void Licznik::Skok_licznika(void) { ile++; } 
 
void Licznik::Pokazuj(void)  
{  
  cout << "Znak " << moja_litera << " wystapil "  
       << ile << " razy" << '\n';  

 
int Suma(int ilosc_obiektow) 

      int i, suma = 0; 
   for(i = 0; i < ilosc_obiektow; i++) 
      suma += TAB[i].ile; 
 
      return (suma); 

 
Tak działa funkcja typu friend. Zwróćmy tu uwagę, że funkcja 
taka nie jest traktowana dokładnie tak samo, jak metoda 
wchodząca w skład klasy i obiektu. Metoda, czyli "własna" 
funkcja obiektu odwołuje się do jego pola (danych) w taki 
sposób: 
 
void Licznik::Skok_licznika(void) 

    ile++;                 //Wiadomo o ktory obiekt chodzi 

 
Funkcja klasy friend odwołuje się do pól obiektów tak: 
 
int Suma(int liczba) 

 ...
     suma += TAB[i].ile;
/* - wymaga dodatkowo wskazania, o który obiekt chodzi - */

 
Należy pamiętać, że dla funkcji kategorii friend wszystkie 
obiekty należące do danej klasy mają status public - są 
dostępne. 
 
O ZAPRZYJAŹNIONYCH KLASACH. 
 
W C++ mogą być zaprzyjaźnione ze sobą wzajemnie także klasy. 
Pozwala to metodom zdefiniowanym wewnątrz jednej z klas na 
dostęp do prywatnych danych obiektów innych klas. W przypadku 
zaprzyjaźnionych klas słowem kluczowym friend poprzedzamy nazwę 
klasy (a nie każdej zaprzyjaźnionej metody z osobna, choć 
zamierzony skutek właśnie na tym polega). Oto praktyczny 
przykład zaprzyjaźnionych klas. 
 
[P109.CPP]
 
# include <iostream.h> 
 
class Data1;          //Deklaracja (a nie definicja!) klasy
 
class TEZ_DATA 

  int dz, rok; 
public: 
  TEZ_DATA() {} 
  TEZ_DATA(int d, int y) { dz = d; rok = y;} 
  void Pokazuj() {cout << '\n' << rok << '-' << dz;} 
  friend Data1;                       //"zaprzyjazniona" klasa
}; 
 
class Data1                           //Tu DEFINICJA klasy

  int mc, dz, rok; 
public: 
  Data1(int m, int d, int y) { mc = m; dz = d; rok = y; } 
  operator TEZ_DATA(); 
}; 
 
static int TAB[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 
 
/* ---- funkcja - metoda konwersji - definicja ----------- */
 
Data1::operator TEZ_DATA(void) 

  TEZ_DATA DT_Obiekt(0, rok); 
  for (int i = 0; i < mc-1; i++) 
  DT_Obiekt.dz += TAB[i]; 
  DT_Obiekt.dz += dz; 
  return DT_Obiekt; 

 
main() 

  Data1 dt_Obiekt(11,17,89); 
  TEZ_DATA DT_Obiekt; 
  DT_Obiekt = dt_Obiekt; 
  DT_Obiekt.Pokazuj(); 
 
return 0;

 
Zaprzyjaźnione są klasy Data1 i TEZ_DATA. Dzięki temu metody 
zadeklarowane wewnątrz zaprzyjaźnionej klasy Data1 mają dostęp 
do prywatnych danych obiektów klasy TEZ_DATA. Ponieważ klasa to 
nowy formalny typ danych, a obiekt to dane takiego nowego typu, 
nic nie stoi na przeszkodzie, by obiekty przekazywać do funkcji 
jako argumenty (tak jak wcześniej obiekty typów typowych - int, 
float itp.). 
 
W C++ mamy jeszcze jedną metodę wymiany danych. Możemy nadać 
elementom klas i obiektów status static (statyczny). 
 
WYMIANA INFORMACJI PR ...

Ciąg dalszy w pliku do pobrania.

Wkuwanko.pl jako podmiot świadczący usługę hostingu materiałów edukacyjnych nie ponosi odpowiedzialności za ich zawartość.

Aby zgłosić naruszenie prawa autorskiego napisz do nas.

ikona Pobierz ten dokument

Wróć do kategorii

wkuwanko.pl

Wasze komentarze: dodaj komentarz

  • Nie ma jeszcze komentarzy do tego materiału.

Materiały w kategorii C++ Dla Zaawansowanych [22]

  • podgląd pobierz opis LEKCJA 25. Przykład obiektu
  • podgląd pobierz opis LEKCJA 27. Dziedziczenie
  • podgląd pobierz opis LEKCJA 28. Dziedziczenie złożone
  • podgląd pobierz opis LEKCJA 29. Funkcje i overloading
  • podgląd pobierz opis LEKCJA 30. Wymiana danych między obiektami
  • podgląd pobierz opis LEKCJA 31. Przekazanie obiektów jako argumentów do funkcji
  • podgląd pobierz opis LEKCJA 33. Wskaźniki do obiektów
  • podgląd pobierz opis LEKCJA 34. Overloading operatorów
  • podgląd pobierz opis LEKCJA 35. O zastosowaniu dziedziczenia
  • podgląd pobierz opis LEKCJA 36. Funkcje wirtualne i klasy abstrakcyjne
  • podgląd pobierz opis LEKCJA 37. Jak komputer dysponuje swoimi zasobami w środowisku tekstowym (DOS)
  • podgląd pobierz opis LEKCJA 38. Programowanie dla Windows
  • podgląd pobierz opis LEKCJA 39. Wykorzystanie standardowych zasobów Windows
  • podgląd pobierz opis LEKCJA 40. Struktura programu proceduralno-zdarzeniowego
  • podgląd pobierz opis LEKCJA 41. Jak tworzy się aplikację dla Windows
  • podgląd pobierz opis LEKCJA 42. Kompilaroty specjalnie dla Windows
  • podgląd pobierz opis LEKCJA 43. Elementy sterujące i zarządzanie programem
  • podgląd pobierz opis LEKCJA 44. Okna dialogowe
  • podgląd pobierz opis LEKCJA 45. Dołączanie zasobów - menu i okienka dialogowe
  • podgląd pobierz opis LEKCJA 46. Programy obiektowo-zdarzeniowe
[ Misja ] [ Regulamin ] [ Kontakt ] [ Reklama ]   © wkuwanko.pl 2008-2019 właściciel serwisu SZLIFF

Partnerzy: matzoo.pl matmag.pl batmat.pl onlinefm.pl pisupisu.pl Matematyka radio online