Wstęp
Tym razem przygotuj się na coś trudniejszego - będzie o wiele więcej trudniejszego materiału. Taką mam nadzieję. :)
Będziemy omawiać bardziej zaawansowane rzeczy niż dotychcasz. Tak jak zdanie wyżej, taką mam nadzieję. ;)
Szablony Klas - Wstęp
Najpierw nasz ulubiony szablon:
template < class klasa >
Teraz piszę już cały przykładowy kod. Chcę zaprezentować jak to działa, choć ten kod może być nieużyteczny. Na razie bez szablonów:
#include <iostream>
class tablica_typu_int
{
public:
int zmienna[ 8 ];
void uzupelnij( int ktora )
{
std::cin >> zmienna[ ktora ];
}
void pokaz( int ktora )
{
std::cout << zmienna[ ktora ] << std::endl;
}
};
int main()
{
tablica_typu_int nowa;
int a = 0;
while( a < 8 )
{
nowa.uzupelnij( a );
nowa.pokaz( a );
std::cout << a << std::endl;
a++;
}
std::cout << "Operacja ukończona - " << a << std::endl;
}
Nasza tablica ma 8 elementów typu int. Nie możemy jej jednak modyfikować.
Teraz mała modyfikacja. Dzięki niej możemy stworzyć tablicę o podanej przez nas wielkości(niestety na razie typu int. :(, ale do tego wktótce dojdziemy):
#include <iostream>
using namespace std;
template < int ilosc >
class tablica_typu_int
{
public:
int zmienna[ ilosc ];
int zmienna_zawierajaca_prawidlowa_ilosc;
void uzupelnij( int ktora )
{
cin >> zmienna[ ktora ];
}
void pokaz( int ktora )
{
cout << zmienna[ ktora ] << endl;
}
int wielkosc()
{
return ilosc;
}
void nadaj_prawidlowa_ilosc()
{
zmienna_zawierajaca_prawidlowa_ilosc = ilosc;
}
};
int main()
{
tablica_typu_int < 11 > nowa;
nowa.nadaj_prawidlowa_ilosc();
int a = 0;
cout << "Nasza tablica to: " << nowa.wielkosc() << " elementow." << endl << endl;
while( a < nowa.zmienna_zawierajaca_prawidlowa_ilosc )
{
nowa.uzupelnij( a );
nowa.pokaz( a );
cout << a << endl;
a++;
}
cout << "Operacja ukończona - " << a << endl;
}
Ostatnia modyfikacja. Tym razem sami możemy "powiedzieć", jakiego typu jest:
#include <iostream>
using namespace std;
template < int ilosc, class typ >
class tablica_typu_int
{
public:
typ zmienna[ ilosc ];
int zmienna_zawierajaca_prawidlowa_ilosc;
void uzupelnij( int ktora )
{
cin >> zmienna[ ktora ];
}
void pokaz( int ktora )
{
cout << zmienna[ ktora ] << endl;
}
int wielkosc()
{
return ilosc;
}
void nadaj_prawidlowa_ilosc()
{
zmienna_zawierajaca_prawidlowa_ilosc = ilosc;
}
};
int main()
{
tablica_typu_int < 21, char > nowa;
nowa.nadaj_prawidlowa_ilosc();
int a = 0;
cout << "Nasza tablica to: " << nowa.wielkosc() << " elementow." << endl << endl;
while( a < nowa.zmienna_zawierajaca_prawidlowa_ilosc )
{
nowa.uzupelnij( a );
nowa.pokaz( a );
cout << a << std::endl;
a++;
}
cout << "Operacja ukończona - " << a << endl;
}
Podsumowując - tworzenie template'a jest takie same zawsze. Jednakże template może służyć do rozmaitych rzeczy.
More Hardcore
Dynamiczne zmienne klas a template
Jest z tym trochę więcej filozofii... Mam nadzieję, że przeczytałeś kurs o dynamiczności w tworzeniu klas? Oto kod:
#include <iostream>
using namespace std;
template < class typ >
class nowa_zmienna
{
typ zmienna;
public:
nowa_zmienna()
{
cout << "Nowy obiekt klasy `tablica` został stworzony" << endl;
}
int wyswietl()
{
cout << "Wyswietlam cos " << 'd' << endl;
}
~nowa_zmienna()
{
cout << "Nowy obiekt klasy `tablica` został zniszczony" << endl;
}
};
int main()
{
nowa_zmienna < int >* nowa = new nowa_zmienna < int >;
nowa->wyswietl();
delete nowa;
}
Ta dynamika prawie niczym się nie różni od zwykłej. Prawie, zauważ jednak, że przy tworzeniu nowego obiektu trzeba dodać template.
Template a... konstruktor
Może się teraz zdziwisz, ale template może częściowo zastępować... konstruktor(z argumentami).
Dlaczego?
#include <iostream>
using namespace std;
class tablica
{
int zmienna;
public:
tablica( int wartosc )
{
zmienna = wartosc;
}
int wyswietl()
{
return zmienna;
}
~tablica()
{
}
};
int main()
{
tablica * nowa = new tablica( 222 );
cout << nowa->wyswietl() << endl;
delete nowa;
}
Taki zapis możesz zmienić... Tak:
#include <iostream>
using namespace std;
template < int wartosc >
class tablica
{
int zmienna;
public:
tablica()
{
zmienna = wartosc;
}
int wyswietl()
{
return zmienna;
}
~tablica()
{
}
};
int main()
{
tablica < 222 >* nowa = new tablica < 222 >;
cout << nowa->wyswietl() << endl;
}
Już nie trzeba bawić się w konstruktory z argumenatami. :)
Definiujemy i deklarujemy z użyciem template'ów osobno
#include <iostream>
using namespace std;
template < class typ >
class nowa_zmienna
{
typ zmienna;
public:
int wyswietl();
};
template < class typ >
int nowa_zmienna < typ >::wyswietl()
{
cout << "sasasfsadgdfcnfghndfhb" << endl;
}
int main()
{
nowa_zmienna < int > nowa;
nowa.wyswietl();
}
Na zakończenie
No to już chyba koniec minikursu... :)
Polecam poeksperymentować z szablonami... :D