Programowanie obiektowe, wyklad8, Kolekcje


Programowanie uogólnione

// klasa wzorcowa (szablonowa)

template <class T> class Stos {

T *wsk_stosu; // adres tablicy dla stosu

int wierzcholek; // indeks wierzchołka stosu

int max_rozmiar; // rozmiar tablicy dla stosu

public:

class Niedomiar {}; // klasa dla wyjątku (pusty stos)

class Nadmiar {}; // klasa dla wyjątku (przepełnienie stosu)

class Zly_rozmiar {}; // klasa dla wyjątku (zły rozmiar stosu)

Stos (int s); // konstruktor

~Stos(); // destruktor

void wloz(T);

T zdejmij();

};

...

template<classT> void Stos<T>::wloz(T c)

{

if (wierzcholek == max_rozmiar) throw Nadmiar();

v[wierzcholek]=c;

wierzcholek++;

}

template<class T> T Stos<T>::zdejmij()

{

if (wierzcholek == 0) throw Niedomiar();

wierzcholek--;

return v[wierzcholek]

}

W main:

// używanie stosu

Stos<char> znaki(10) // stos 10 znaków

Stos<int> liczby(5) // stos 5 liczb całkowitych

Stos<zesplone> lz(10) // stos 10 liczb zespolonych

Przykład 2: Obsługa kolejki FIFO, kolejka przechowywana jest w tablicy

template <class Typ> class FIFO {

Typ *t;

int glowa, ogon, max_el;

public:

FIFO(int n) {

max_el=n;

glowa=ogon=0;

t=new Typ[max_el];

}

void wstaw (Typ x) {

t[ogon++]=x;

if (ogon>max_el) ogon=0;

}

int obsluz(Typ &w) {

if (glowa==ogon) return -1;

w=t[glowa++];

if (glowa>max_el) glowa=0;

return 1;

}

int pusta() {

if (glowa==ogon)

return 1;

else

return 0;

}

};

#include <iostream>

int main() {

FIFO<char*> kolejka(3);

char *tab[]={"Nowak",

"Adamska", "Burski"};

for (int i=0; i<3; i++)

kolejka.wstaw(tab[i]);

for (int i=0; i<5; i++)

{

char *s;

int res=kolejka.obsluz(s);

if (res==1)

cout << "Obsluzony klient: "

<< s << endl;

else {

cout << "Kolejka pusta!\n";

break;

}

}

}

Klasy pojemnikowe (ang. container class)

Przykład prostej klasy pojemnikowej

// Klasa do przechowywania liczb całkowitych

0x08 graphic
class schowek {

int liczba;

public:

0x08 graphic
void schowaj

0x08 graphic
(int x) { liczba = x }

int oddaj()

{ return liczba; }

};

// Ta sama klasa zapisana za pomocą wzorca

template <class typObiektu> class schowek {

typObiektu liczba;

public:

void schowaj(typObiektu x)

{ liczba = x }

typObiektu oddaj()

{ return liczba; }

};

Przykład klasy do przechowywania obiektów własnego typu

#include <iostream>

#include <string>

struct Osoba{

string imie;

int wiek;

};

ostream& operator << (ostream& wy, Osoba& os)

{

wy << os.imie << ' ';

wy << os.wiek << ' ';

return wy;

}

istream& operator >> (istream& we, Osoba& os)

{

cout << "Wpisz imie: ";

we >> os.imie;

cout << "Wpisz wiek: ";

we >> os.wiek;

return (we);

}

template <class T> class Dane {

private:

T d;

public:

Dane() {};

Dane(T n);

void Wczytaj();

void Drukuj();

};

template <class T> Dane<T>::Dane(T n)

{

d=n;

}

template <class T> void Dane<T>::Drukuj()

{

cout << d << endl;

}

template <class T> void Dane<T>::Czytaj()

{

cin >> d;

}

main ()

{

Dane<Osoba> x;

x.Czytaj();

x.Drukuj();

return 0;

}

Typy pojemników

Pojemniki z biblioteki STL (Standard Template Library)

vector<float> ld; /* pusty wektor elementów typu float */

list <int> li; /* pusta lista elementów typu int */

list<punkt> lp; /* pusta lista elementów typu punkt */

Operacje

Pojemnik

vector

list

deque

operacje na początku

trudne

łatwe

łatwe

operacje w środku

trudne

łatwe

trudne

operacje na końcu

łatwe

łatwe

łatwe

dostęp do elementów

natychmiastowy

żmudny

natychmiastowy

Przykład klasy pojemnikowej typu wektor - wersja specjalizowana do przechowywania obiektów klasy osoba

/* J.Grębosz, Pasja C++ , wyd.2, str. 246-274 */

const int pojemnosc_wektora = 20 ;

class wektor{

osoba tabl[pojemnosc_wektora];

int ile_ob ;

public:

wektor() : ile_obiektow(0) { }

int wstaw(const osoba & nowy, int gdzie = -1);

void usun(int nr);

osoba & co_na(int pozycja)

{ return tabl[pozycja]; }

friend ostream& operator<<(ostream & s, wektor & x);

private:

void rozsun(int pozycja);

void zsun(int nr);

};

ostream& operator<<(ostream& s, wektor& spis)

{

stru << " " ;

for(int i = 0 ; i < spis.ile_ob ; i++)

stru << i << ") " << spis.tabl[i] << " " ;

stru << endl ;

return stru ;

}

void wektor::rozsun(int pozycja){

for(int i = ile_ob ; i > pozycja ; i--)

tabl[i] = tabl[i-1];

}

void wektor::zsun(int nr)

{

for(int i = nr ; i < ile_ob ; i++) {

tabl[i] = tabl[i+1];

}

int wektor::wstaw(const osoba & nowy, int gdzie)

{

if(ile_ob == pojemnosc_wektora) {

cout << "wektor juz zapelniony\n" ;

return 0;

}

if(gdzie < 0 || gdzie > ile_ob)

gdzie = ile_ob;

rozsun(gdzie);

tabl[gdzie] = nowy ;

ile_obiektow++;

return 1 ;

}

void wektor::usun(int nr){

if(nr < ile_ob) {

zsun(nr);

ile_obiektow--;

}

}

#include "osoba.h"

main() {

wektor studenci ;

osoba s1("Kowalski");

osoba s2("Nowak");

studenci.wstaw(s1);

studenci.wstaw(s2);

cout << "Zawartosc spisu studentow:\n"

<< studenci ;

osoba s3("Bender");

studenci.wstaw(s3);

cout << "Zawartosc spisu studentow:\n"

<< studenci ;

return 0 ;

}

class osoba {

char nazwisko[30] ;

public:

osoba(char* n= 0)

{ if (n) strcpy(nazwisko, n); }

friend ostream & operator<<(ostream &s, const osoba & o);

friend ostream & operator<<(ostream &s, const osoba * wsk);

};

ostream & operator<<(ostream &s, const osoba & o){

s << o.nazwisko ;

return s ;

}

ostream & operator<<(ostream &s, const osoba * wsk){

s << wsk->nazwisko ;

return s ;

}

Przykład klasy pojemnikowej typu wektor - wersja z klasą wzorcową (szablonową)

/* J.Grębosz, Pasja C++, wyd.2, str. 246-274 */

#include <iostream.h>

#include <string.h>

const int pojemnosc_wektora = 15 ;

template <class twoj_typ>

class wektor{

twoj_typ tabl[pojemnosc_wektora];

int ile_ob ;

public:

wektor() : ile_ob(0) { }

int wstaw(const twoj_typ & nowy, int gdzie = -1);

void usun(int nr);

twoj_typ & co_na(int pozycja)

{ return tabl[pozycja] ; }

friend ostream & operator<<

(ostream & stru ,wektor<twoj_typ>& x);

private:

void wektor::rozsun(int pozycja);

void zsun(int nr);

};

template <class twoj_typ>

void wektor<twoj_typ>::rozsun(int pozycja)

{

for(int i = ile_ob; i > pozycja; i--)

tabl[i] = tabl[i-1];

}

template <class twoj_typ>

void wektor<twoj_typ>::zsun(int nr)

{

for(int i = nr ; i < ile_ob ; i++)

tabl[i] = tabl[i+1];

}

template <class twoj_typ>

int wektor<twoj_typ>::wstaw(const twoj_typ & nowy, int gdzie)

{

if(ile_ob == pojemnosc_wektora) {

cout << "wektor juz zapelniony\n" ;

return 0;

}

if(gdzie < 0 || gdzie > ile_ob)

gdzie = ile_obiektow;

rozsun(gdzie);

tabl[gdzie] = nowy ;

ile_obiektow++;

return 1 ;

}

template <class twoj_typ>

void wektor<twoj_typ>::usun(int nr)

{

if(nr < ile_ob.) {

zsun(nr);

ile_obiektow--;

}

}

template <class twoj_typ>

ostream & operator<<(ostream & stru, wektor<twoj_typ> &spis)

{

stru << " " ;

for(int i=0; i < spis.ile_ob ; i++)

stru << i << ") " << spis.tabl[i] << " " ;

stru << endl ;

return stru ;

}

#include <osoba.h>

main() {

wektor<osoba> studenci ;

osoba s1("Kowalski"), s2("Nowak");

studenci.wstaw(s1);

studenci.wstaw(s2);

cout << "Zawartosc spisu studentow:\n"

<< studenci ;

osoba s3("Bender");

studenci.wstaw(s3);

cout << "Zawartosc spisu studentow:\n"

<< studenci ;

wektor<osoba*> pracownicy;

osoba *wsk1;

wsk1=new osoba("Adamska");

osoba *wsk2;

wsk2=new osoba("Kunik");

osoba wsk3("Hercen");

pracownicy.wstaw(wsk1);

pracownicy.wstaw(wsk2);

pracownicy.wstaw(&wsk3,0);

cout << "Zawartosc spisu pracownikow:\n" << pracownicy;

wektor<char> literki;

literki.wstaw('b');

literki.wstaw('c');

literki.wstaw('a',0);

cout << "Pojemnik zawiera literki:\n" << literki;

return 0;

}

Przykłady użycia klasy pojemnikowej vector z biblioteki STL

(por. wykład 4)

Przykład:

#include <vector>

#include <iostream>

using namespace std;

void main()

{

vector <int> vi;

// czytaj z klawiatury liczby, aż zostanie wpisane 0

for (;;)

{

int robocza;

cout<<"Wpisz liczbe; napisnij 0 aby zakonczyc" <<endl;

cin>>robocza;

if (robocza == 0 ) break;

vi.push_back(robocza); // wstaw liczbę na koniec buforu vi

}

cout<< "Wstawiles "<< vi.size()

<<" elementow do pojemnika " << endl;

}

Użyte funkcje:

push_back() - dodaj element na końcu pojemnika, zwiększ o 1 liczbę elementów przechowywanych

w pojemniku

size() - podaj liczbę elementów przechowywanych w pojemniku

#include <vector>

#include <iostream>

#include <string>

using namespace std;

void main()

{

vector <string> vs;

for (;;)

{

string robocza;

cout<<"Wpisz tekst i nacisnij Enter; aby zakoczyc wpisz \"stop\" "

<<endl;

cin>>robocza;

if (robocza == "stop" ) break;

vs.push_back(robocza);

}

cout<< " Wstawiles "<< vs.size() <<" elementow do pojemnika "

<< endl;

}

Przykład: drukowanie składowych wektora rozdzielanych spacją

#include <iostream>

#include <vector>

using namespace std ;

void drukuj(vector<int> &);

int main()

{

int i ;

int t[] = {1,2,3,4,5,6,7,8,9,10} ;

vector<int> v(t,t+10);

drukuj(v);

return 0;

}

void drukuj(vector<int> &v)

{

cout << '{ ' ;

for (int i=0 ; i<v.size(); i++)

cout << v[i] << ' ' ; // dostęp do elementów wektora

cout << '}' << endl;

}

#include <vector>

#include <iostream>

#include <string>

using namespace std;

void main()

{

vector <string> vs;

string roboczy = "Dzien dobry";

vs.push_back(roboczy);

cout<<"Wstawiono za pomoca []: "<< vs[0] <<endl;

cout<<"Wstawiono za pomoca at(): "<< vs.at(0) <<endl;

roboczy = "Witam";

vs[0] = roboczy;

cout<<"Modyfikacja za pomoca []: "<< vs[0] <<endl;

roboczy = "Czesc";

vs.at(0) = roboczy;

cout<<"Modyfikacja za pomoca at(): "<< vs.at(0) <<endl;

}

Pojemnik automatycznie zwiększa pamięć, gdy tego potrzebuje. Oznacza to kopiowanie przechowywanych obiektów w inne miejsce. Nie zawsze to sprzyja wydajności.

Przykład:jedna z strategii postępowania - aloakacja wystarczająco dużej pamięci, gdy potrafimy przewidzieć potrzeby. Np. wiemy, że serwer pocztowy potrzebuje dużo pamięci tylko w godzinach szczytu i potrafimy to zapotrzebowanie oszacować.

#include <iostream>

#include <vector>

using namespace std;

// uproszczona wiadomość pocztowa

struct message { char text[1000];};

class MailServer {

public:

bool RushHour() const; // czy godziny szczytu

bool MoreMessages() const; // czy nadchodzą dalsze wiadomości

message& GetNewMsg() const; // pobierz wiadomość

};

bool MailServer::RushHour() const

{

bool rush = true;

return rush;

}

bool MailServer::MoreMessages() const

{

bool more = true;

return more;

}

message& MailServer::GetNewMsg() const

{

static message msg;

return msg;

}

void main()

{

MailServer server;

vector <message> vm;

if (server.RushHour())

vm.reserve(5000); // zarezerwuj dostaczenie dużo pamięci

while (server.MoreMessages())

{

static int count =0;

vm.push_back( server.GetNewMsg() );

if (count > 5000)

break;

}

}

Przglądanie elementów pojemnika czyli iteratory

#include <iostream>

#include <vector>

using namespace std;

void main()

{

vector <double> zarobki;

zarobki.push_back(2300.2);

zarobki.push_back(1860.4);

zarobki.push_back(3450.);

vector<double>::iterator p = zarobki.begin();

while ( p != zarobki.end())

{

cout<<"Zarobki przed podwyzka: "<< *p <<endl;

*p = *p * 1.15;

cout<<"Zarobki po 15% podwyzce: "<< *p <<endl;

p++;

}

}

Przykład listy podwójnie dowiązywanej z iteratorami

/* J.Grębosz, Pasja C++, wyd.2, str. 336-378 */

// plik Dlista.h

template <class typOBJ> class iteratorL ; // iterator

// Wzorzec listy podwójnie dowiązywanej

template <class typOBJ> class DLista{

struct wezel {

typOBJ * wskobj ;

wezel * nastepca ;

wezel * poprzednik;

wezel():nastepca(NULL),wskobj(NULL),poprzednik(NULL)

{ }

};

wezel *pierwszyW ;

wezel *ostatniW ;

int dlugosc ;

public:

typedef iteratorL<typOBJ> itLis ;

DLista() {

pierwszyW = ostatniW = NULL;

dlugosc = 0 ;

}

~DLista();

void wstaw(typOBJ & obj, itLis & iter);

void wstaw(typOBJ & obj, int nr)

{

itLis iter(*this);

iter.na_wezel(nr) ;

wstaw(obj, iter) ;

}

void wstaw(typOBJ & obj)

{

itLis iter(*this);

iter.za_koniec();

wstaw(obj, iter) ;

}

void usun(itLis & iter);

void usun(int nr)

{

itLis it(*this);

usun(it.na_wezel(nr)) ;

}

int rozmiar() const

{

return dlugosc ;

}

private:

void daje_na_poczatek(wezel* nowyW, itLis & iter);

void daje_w_srodku(wezel* nowyW, itLis & iter);

void daje_na_koniec(wezel* nowyW);

void usuwam_pierwszy(itLis & iter);

void usuwam_ostatni(itLis & iter);

void usuwam_ze_srodka(itLis & iter);

friend ostream & operator<<(ostream & stru, DLista<typOBJ> & x);

friend class iteratorL<typOBJ> ;

};

template <class typOBJ>

void DLista<typOBJ>::wstaw(typOBJ & obj, itLis & iter)

{

wezel * nowyW = new wezel ;

nowyW->wskobj = &obj ;

dlugosc++ ;

if(iter.wybranyW !=NULL)

{

if(iter.wybranyW==pierwszyW)

daje_na_poczatek(nowyW, iter);

else

daje_w_srodku(nowyW, iter);

}

else daje_na_koniec(nowyW);

}

template <class typOBJ>

void DLista<typOBJ>::daje_na_poczatek(wezel* nowyW,itLis& iter)

{

pierwszyW = nowyW ;

nowyW->nastepca = iter.wybranyW ;

iter.wybranyW->poprzednik = nowyW ;

nowyW->poprzednik = NULL ;

iter.wybranyW = nowyW ;

}

template <class typOBJ>

void DLista<typOBJ>::daje_w_srodku(wezel* nowyW, itLis & iter)

{

(iter.wybranyW->poprzednik)->nastepca = nowyW;

nowyW->nastepca = iter.wybranyW ;

nowyW->poprzednik=iter.wybranyW->poprzednik;

iter.wybranyW->poprzednik = nowyW ;

}

template <class typOBJ>

void DLista<typOBJ>::daje_na_koniec(wezel* nowyW)

{

if(!pierwszyW)

pierwszyW = nowyW ;

else {

ostatniW->nastepca = nowyW ;

nowyW->poprzednik = ostatniW ;

}

ostatniW = nowyW ;

}

template <class typOBJ>

void DLista<typOBJ>::usun(itLis & iter)

{

if(iter.wybranyW == NULL)return ;

dlugosc-- ;

if(iter.wybranyW == pierwszyW)

usuwam_pierwszy(iter);

else

{

if(iter.wybranyW == ostatniW)

usuwam_ostatni(iter);

else

usuwam_ze_srodka(iter);

}

}

template <class typOBJ>

void DLista<typOBJ>::usuwam_pierwszy(itLis & iter)

{

pierwszyW = pierwszyW->nastepca;

delete iter.wybranyW ;

iter.wybranyW = pierwszyW ;

pierwszyW->poprzednik = NULL ;

}

template <class typOBJ>

void DLista<typOBJ>::usuwam_ze_srodka(itLis & iter)

{

wezel * poprzW = iter.wybranyW->poprzednik;

poprzW->nastepca = iter.wybranyW->nastepca ;

(iter.wybranyW->nastepca)->poprzednik = poprzW;

delete iter.wybranyW ;

iter.wybranyW = poprzW ;

}

template <class typOBJ>

void DLista<typOBJ>::usuwam_ostatni(itLis & iter)

{

wezel * poprzW = iter.wybranyW->poprzednik;

poprzW->nastepca = NULL ;

ostatniW = poprzW ;

delete iter.wybranyW ;

iter.wybranyW = NULL ;

}

template <class typOBJ>

DLista<typOBJ>::~DLista()

{

itLis iter(*this) ;

for(int i = 0 ; i < dlugosc ; i++)

delete (iter++).wybranyW ;

}

template <class typOBJ>

ostream & operator<<(ostream & stru , DLista<typOBJ> & spis)

{

iteratorL<typOBJ> skoczek(spis) ;

for(int i = 0 ; i < spis.rozmiar() ; i++)

{

stru << i << ") " << *(skoczek++) << " " ;

if(!( (i+1)%3 ))

stru << endl ;

}

stru << endl ;

return stru ;

}

// wzorzec iteratora

template <class typOBJ> class iteratorL

{

protected:

friend class DLista<typOBJ> ;

DLista<typOBJ>::wezel * wybranyW ; // wskaźnik do aktualnego węzeła listy

DLista<typOBJ> & pojemnik ; // referencja do obsługiwanego pojemnika

public:

iteratorL(DLista<typOBJ> & pojem) : pojemnik(pojem)

{

wybranyW=pojemnik.pierwszyW;

}

iteratorL & na_poczatek()

{

wybranyW = pojemnik.pierwszyW ;

return *this ;

}

iteratorL & na_koniec()

{

wybranyW = pojemnik.ostatniW;

return *this ;

}

iteratorL & za_koniec()

{

wybranyW = NULL ;

return *this ;

}

iteratorL & operator++()

{

wybranyW = wybranyW->nastepca ;

return *this;

}

iteratorL & operator--()

{

wybranyW = wybranyW->poprzednik ;

return *this;

}

iteratorL operator++(int)

{

iteratorL stary = *this;

++*this;

return stary;

}

iteratorL operator--(int)

{

iteratorL stary = *this;

--*this;

return stary;

}

typOBJ & operator*()

{

return *(wybranyW ->wskobj) ;

}

iteratorL & na_wezel(int nr);

iteratorL & operator=(const iteratorL & prawy)

{

wybranyW = prawy.wybranyW ;

return *this;

}

int operator==(const iteratorL & prawy)

{

if(wybranyW == prawy.wybranyW) return 1 ;

else return 0 ;

}

int operator!=(const iteratorL & prawy)

{

if(wybranyW != prawy.wybranyW) return 1 ;

else return 0 ;

}

operator int()

{

if(wybranyW != NULL) return 1;

else return 0;

}

};

template <class typOBJ>

iteratorL<typOBJ> & iteratorL<typOBJ>::na_wezel(int nr)

{

wybranyW = pojemnik.pierwszyW ;

for(int i = 0 ; i < nr ; i++, ++(*this) );

return *this ;

}

// Lista wykorzystana jest do przechowywania opisów punktów

// kontrolnych biegu terenowego

#include <iostream.h>

#include <iomanip.h>

#include <string.h>

#include "osoba.h"

#include "Dlista.h"

main()

{

osoba

punktD("Stary Dab"),

punktG("Glaz nad strumieniem"),

punktA("Ambona mysliwska"),

punktW("Wyspa"),

punktKP("Kurhan"),

punktKA("Kamieniolom");

DLista<osoba> trasa ; // definicja pojemnika

// organizator biegu ustawia kolejne punkty kontrolne

iteratorL<osoba> organizator(trasa);

trasa.wstaw(punktD, organizator);

trasa.wstaw(punktG, organizator);

trasa.wstaw(punktA, organizator);

trasa.wstaw(punktW, 1);

trasa.wstaw(punktKP, organizator);

cout << trasa << endl;

cout << "Wyspa na zlej pozycji, skorygujemy to\n" ;

trasa.usun(1);

organizator.na_wezel(3) ;

trasa.wstaw(punktW, organizator);

cout << trasa << endl;

// mamy dwóch uczestników, którzy rozpoczynają bieg z dwóch przeciwstawnych

// końców

cout << "---- Dwa przeciwbiezne iteratory ------\n";

iteratorL<osoba> Kasia(trasa);

iteratorL<osoba> Marek(trasa);

Marek.na_koniec();

// --- przebiegniecie trasy

cout << setw(20) << "Kasia:"<<" "<< setw(20) << "Marek:"<<endl ;

for(int i = 0 ; i < trasa.rozmiar() ; i++,Kasia++)

cout<< setw(20)<< *Kasia << " "

<< setw(20) << *(Marek--)<< endl ;

cout << endl;

cout << "Dla utrudnienia dolaczamy kamieniolom\n";

trasa.wstaw(punktKA, 3);

cout << trasa <<endl;

// rozpoczynamy jeszcze raz

Kasia.na_koniec();

Marek.na_poczatek();

cout << setw(20) << "Kasia:"<<" "<< setw(20) << "Marek:"<<endl ;

for(int i = 0 ; i < trasa.rozmiar() ; i++)

cout << setw(20) << *(Kasia--) << " "

<< setw(20) << *(Marek++) << endl ;

cout << endl;

cout << "Ktos nie umie plywac, wiec usuniecie wyspy\n" ;

trasa.usun(3);

cout << trasa ;

// oszczedzmy sobie juz biegania.....

}

Złożone operacje wykonywane na pojemnikach czyli algorytmy

Przykład 1: kopiowanie

#include <iostream>

#include <vector>

#include <list>

#include <algorithm>

using namespace std ;

main()

{ int t[5] = { 1, 2, 3, 4, 5 } ;

vector<int> v(t, t+5) ; /* v zawiera : 1, 2, 3, 4, 5 */

list<int> l(8, 0) ; /* lista 8 elementów równych 0 */

void drukuj(vector<int>) ;

void drukuj(list<int>) ;

cout << "lista poczatkowa : " ; drukuj(l) ;

copy (v.begin(), v.end(), l.begin()) ;

cout << "lista po 1-szym kopiowaniu : " ; drukuj(l) ;

l.erase(l.begin(), l.end()) ; /* l jest teraz pusta */

copy (v.begin(), v.end(), inserter(l, l.begin())) ;

cout << "lista po 2-gim kopiowaniu : " ; drukuj(l) ;

}

void drukuj(list<int> l)

{ list<int>::iterator il ;

for (il=l.begin() ; il!=l.end() ; il++) cout << *il << " " ;

cout << "\n" ;

}

1

20



Wyszukiwarka

Podobne podstrony:
Programowanie obiektowe, wyklad6-czesc1, Dziedziczenie wielobazowe
11 10 2011 programowanie obiektowe wykład
Programowanie obiektowe, wyklad5, Dziedziczenie
Programowanie obiektowe wykład
Programowanie Obiektowe wykłady
wyklad5.cpp, JAVA jest językiem programowania obiektowego
Wyklad 3-4, uwm wnt Mecha, SM 5, Programowanie obiektowe i strukturalne, Wykłady
Wyklad 5-6, uwm wnt Mecha, SM 5, Programowanie obiektowe i strukturalne, Wykłady
Cwiczenie 1, uwm wnt Mecha, SM 5, Programowanie obiektowe i strukturalne, Wykłady
Wykład z programowania obiektowego, Informatyka, Semsetr 2, Programowanie obiektowe
Cwiczenie 4 Rozwiazania, uwm wnt Mecha, SM 5, Programowanie obiektowe i strukturalne, Wykłady
Wyklad 9-10, uwm wnt Mecha, SM 5, Programowanie obiektowe i strukturalne, Wykłady
Wyklad 13-14, uwm wnt Mecha, SM 5, Programowanie obiektowe i strukturalne, Wykłady
Programowanie obiektowe(ćw) 1
Zadanie projekt przychodnia lekarska, Programowanie obiektowe
Programowanie obiektowe w PHP4 i PHP5 11 2005
Programowanie Obiektowe ZadTest Nieznany
13 Bazy danych obiektowość wykładid 14617

więcej podobnych podstron