3.1 Relacje między klasami, klasy zagnieŝdŝone, klasy lokalne... 1 3.2 Zaprzyjaźnione klasy, specyfikator friend... 3 3.3 Zaprzyjaźnione funkcje, metody z klasą... 4 3.4 Relacje dziedziczenia... 6 3.5 Agregacja, kompozycja klas... 9 3.1 Relacje między klasami, klasy zagnieŝdŝone, klasy lokalne Przykład 1. Klasy zagnieŝdŝone w klasach (w04-01-klasyzagniezdzone.cpp). A()cout << "A()" << endl; ~A()cout << "~A()" << endl; class B B(); ~B()cout << "~B()" << endl; int pib() const return ib; int ib; class C C() int pic() const return ic; int ic; class D; // deklaracacja klasy zagnieŝdŝonej A::B::B() cout << "B()" << endl; ib = 100; class A::D // definicja klasy zagnieŝdŝonej void main() A::B b; cout << b.pib() << endl; 1
Przykład 2. Klasa lokalna klasa zagnieŝdŝona w funkcji (w04-02-klasylokalne.cpp). void f() A():i(100) cout << "A()" << endl; ~A() cout << "~A()" << endl; int pi() return i; int i; A a; cout << a.pi() << endl; void main() f(); 2
3.2 Zaprzyjaźnione klasy, specyfikator friend Relacja friend daje moŝliwość zaprzyjaźnionym obiektom dostęp do niepublicznych elementów klasy. Relacja zaprzyjaźnienia moŝe być między klasami, funkcja z klasą, metoda z klasą. Własności: 1. Relacja friend nie jest dziedziczna (przechodnia). 2. Relacja friend nie jest przemienna. 3. Funkcje deklarowane jako friend są traktowane tak, jakby były definiowane za pomocą deklaracji extern (MSDN). Przykład 1. Zaprzyjaźnione klasy (w04-03-klasafriend.cpp). #include <iostream> A():ia(10) cout<< "A()"<< endl; ~A() cout<< "~A()"<< endl; int pia() return ia; friend class B; protected: // // teŝ ok int ia; class B B():ib(100) cout<< "B()"<< endl; ~B() cout<< "~B()"<< endl; void fb(a *p) p->ia = p->ia + ib; // klasa B jest zaprzyjaźniona z A void fb(a & r) r.ia = r.ia + ib; // klasa B jest zaprzyjaźniona z A int ib; void main() A a; B b; b.fb(a); cout << a.pia()<< endl; b.fb(&a); cout << a.pia()<< endl; 3
3.3 Zaprzyjaźnione funkcje, metody z klasą Przykład 1. Zaprzyjaźnione metody z klasą (w04-04-metodafriend.cpp). #include <iostream> class B; class A int f1a(b &); int f2a(b &); class B B():ib(100) friend int A::f1A(B &); int ib; int A::f1A(B& r) return r.ib; // OK, f1a(b&) friend B // int A::f2A(B& r) return r.ib; // błąd, f2a(b&) nie jest friend void main() A a; B b; cout << a.f1a(b); 4
Przykład 2. Zaprzyjaźnione funkcje z klasą (w04-05-funkcjefriend.cpp). #include <iostream> A():i(100)ii=1000; friend void g1(a*, int); // funkcja globalna g(a*) zaprzyjazniona z A friend void g2(a&, int); // funkcja globalna g(a*) zaprzyjazniona z A friend void h(a); protected: int i; int ii; // funkcja globalna h(a) zaprzyjazniona z A void g1(a *pa, int n) // g1(a*) ma dostęp do A::i, A::ii pa->i = n+ pa->ii; void g2(a &r, int n) // g2(a&) ma dostęp do A::i, A::ii r.i = n+ r.ii; void h(a a) cout << a.i << endl; cout << a.ii << endl; // h(a) ma dostęp do A::i, A::ii void main() A a; A &r = a; g1(&a, 20); h(a); g2(r, 30); h(a); 5
3.4 Relacje dziedziczenia Dziedziczenie typu: public (class B : public A), elementy publiczne klasy głównej A są publiczne dla obiektów klasy dziedzicznej B, elementy protected klasy głównej A są protected dla obiektów klasy dziedzicznej B, protected (class B : protected A), elementy publiczne i protected klasy bazowej A są protected dla obiektów klasy pochodnej B, private (class B : private A), (class B : A), elementy publiczne, protected klasy bazowej A są prywatne dla obiektów klasy pochodnej B. Przykład 1. Relacje dziedziczenia, dziedziczenie private (w04-06-dziedziczenie.cpp). A():ia(100), iia(200) int riia() return iia; int ia; int iia; class B : A // class B : private A int f1b() return riia(); int f2b(); int B::f2B() this->ia +=10; return ia; void main() B b; cout << b.f1b() << endl; // metody z B mają dostęp do public A cout << b.f2b() << endl; // metody z B mają dostęp do public A // b.riia(); // błąd dostępu, musi być class B : public A 6
Przykład 1. Dziedziczenie public (w04-07-dziedziczeniepublic.cpp). A() cout << "A()"<< endl; ~A() cout << "~A()"<< endl; void fa() cout << "fa" << endl; class B : public A B()cout << "B()"<< endl; ~B()cout << "~B()"<< endl; void fb() cout << "fb" << endl; void main() B b; // wywoływany jest konstruktor A() i B() b.fb(); b.fa(); // obiekt b ma dostęp do metody z klasy A Przykład 3. Relacja dziedziczenia jest przechodnia (w04-08-dziedziczenieabc.cpp). A() cout << "A()"<< endl; ~A() cout << "~A()"<< endl; void fa() cout << "fa()" << endl; class B : public A B()cout << "B()"<< endl; ~B()cout << "~B()"<< endl; void fb() cout << "fb()" << endl; class C : public B C()cout << "C()"<< endl; ~C()cout << "~C()"<< endl; void fc() cout << "fc()" << endl; void main() C c; // wywoływany jest konstruktor A(), B(), C() c.fb(); // obiekt c ma dostęp do metody public z klasy B c.fa(); // obiekt c ma dostęp do metody public z klasy A 7
Przykład. Dziedziczenie protected (w04-09-dziedziczenieprotected.cpp). #include <iostream> void f1a()cout << "f1a()" << endl; protected: void f2a()cout << "f2a()" << endl; void f3a()cout << "f3a()" << endl; class B : protected A void f1b(); protected: void f2b(); void f3b(); void B::f1B() cout << "f1b()" << endl; f1a(); f2a(); // f3a(); // błąd dostępu void B::f2B() cout << "f2b()" << endl; f1a(); f2a(); // f3a(); // błąd dostępu void B::f3B() cout << "f3b()" << endl; f1a(); f2a(); // f3a(); // błąd dostępu void main() B b; b.f1b(); // b.f1a(); // błąd dostępu 8
3.5 Agregacja, kompozycja klas Definicja. Agregacja jest relacją między klasami, oznacza Ŝe klasa jest częścią innej klasy. Przykład. Agregacja klas (w04-10-agregacaja.cpp). A() cout << "A()" << endl; ~A()cout << "~A()" << endl; void fa()cout << "fa()" << endl; class B B()cout << "B()" << endl; ~B()cout << "~B()" << endl; void fb() pa->fa(); A *pa; void main() B b; // wywoływny jest konstruktor B() b.fb(); 9
Definicja. Kompozycja (złoŝenie, ang. composition) oznacza, Ŝe klasa zawiera instancję innej klasy. Przykład. Kompozycja klas typu private (w04-11-kompozycja.cpp). Czas Ŝycia obiektu a zaleŝy od czasu Ŝycia obiektów klasy B. A()cout << "A()" << endl; ~A()cout << "~A()" << endl; class B B()cout << "B()" << endl; ~B()cout << "~B()" << endl; A a[4]; void main() B b; // wywoływne są 4 konstruktory A(), jeden B() 10