Sunday, October 8, 2017

Kuliah 7 C++: Template



BAB 7.
Template






7.1 Pengantar
Ada banyak program yang bisa melakukan operasi-operasi yang sama pada sejumlah tipe data yang berbeda. Sebagai contoh, dalam mengurutkan list, dimana list memuat sejumlah nilai integer sejumlah atau nilai titik-mengambang atau sejumlah karakter, kode operasionalnya sama. Sama halnya, dalam penukaran dua kuantitas, kodenya identik kecuali untuk tipe data variabelnya. Hal yang sama berlaku pada kasus pencarian kuantitas terbesar dari dua kuantitas, apakah kuantitas itu berupa nilai integer, nilai titik-mengambang, atau berupa karakter. Dalam C++, kapanpun sebuah variabel dideklarasikan, tipe datanya harus disebutkan tepat sebelum nama variabel itu. Oleh karena itu, meskipun kode sama, untuk membuat kode itu bisa diterapkan pada sejumlah tipe data yang berbeda, misalnya pada int, double, atau char, programer perlu menulikan satu prorgram untuk setiap tipa data. Template memberikan fasilitas sehingga Anda tidak perlu menuliskan banyak program dengan kode yang identik (kecuali tipe datanya yang berbeda). Dengan template, Anda hanya perlu menuliskan satu program yang dapat diterapkan pada semua tipe data, baik itu tipe-tipe data fundamental atau pun tipe data yang diciptakan sendiri oleh user. Pada kasus template, program ditulis dengan sebuah pemegang tempat (place holder) menggantikan tipe data. Ketika tipe data disubstitusi, kompiler akan mensubstitusi tipe yang ditetapkan menggantikan pemegang tempat dan mengkompilasi program. Jika tipe data lain ditetapkan, kompiler akan menghasilkan spesialisasi template lain untuk tipe dat itu dan mengkompilasi program.

Pemrograman template juga dikenal dengan pemrograman generik. Template fungsi dan template kelas juga dikenal dengan fungsi generik dan kelas generik. Ada beberapa metode lain untuk melakukan hal yang sama seperti penggunaan makro, #define dan ointer void. Program-program semacam itu digunakan programer sebelum adanya implementasi template.

Penggunaan template dimulai pada tahun 1991. Keuntungan terbesar dari pemrograman generik adalah bahwa ia dapat diterapkan pada semua tipe data, baik pada tipe-tipe data fundamental ataupun pada tipe-tipe data yang didefinisikan sendiri oleh user.



7.2 Template Fungsi
Deklarasi template fungsi dimana di dalamnya fungsi dan parameter-parameternya bertipe sama diilustrasikan berikut. Template fungsi dideklarasikan dengan katakunci template yang diikuti dengan kurung siku yang memuat katakunci typename atau class yang diikuti dengan sebuah pengenal atau nama dari typename atau class, yaitu nama dari pemegang tempat (place holder) untuk tipe data. Pada posisi setelah kurung siku, fungsi didefinisikan. Lihat ilustrasi berikut.

template <typename pengenal_tipe> pengenal_tipe nama_fungsi(pengenal_tipe parameter1, –, –)
  {statemen_statemen;}

Atau, bisa dikode dengan katakunci class menggantikan typename sebagai berikut:

template <class pengenal_tipe> pengenal_tipe nama_fungsi(pengenal_tipe parameter1, –, –)
  {statemen_statemen;}

Pada kedua deklarasi, template, typename, dan class adalah katakunci di dalam C++. Kedua dekalrasi di atas adalah ekivalen. Elemen pengenal_tipe merupakan sembarang pengenal yang valid dalam C++ yang dipakai sebagai pemegang tempat untuk tipe data. Elemen pengenal_tipe yang dipakai untuk class atau typename harus ditempatkan sebelum nama fungsi dan sebelum nama dari tiap parameter fungsi. Sebagai contoh, dimisalkan bahwa T adalah pengenal_tipe atau nama dari typename atau class, maka template fungsi untuk menghitung luas dari sebuah persegi-panjang dengan sisi-sisinya direpresentasikan oleh x dan y dapat didefinisikan sebagai berikut:

template <typename T> T Luas(T x, T y)   //kepala fungsi
{return x * y ; }                        //tubuh fungsi

Di sini, T adalah pengenal_tipe. Lihat bahwa T yang ditempatkan sebelum nama Luas adalah tipe nilai balik dari fungsi Luas. Fungsi tersebut dapat pula didefinisikan dengan katakunci class sebagai berikut:

template <class T> T Luas(T x, T y)             //kepala fungsi
{return x * y ; }                        //tubuh fungsi

Kedua definisi fungsi ekivalen dan salah satunya dapat digunakan. Di sini, T adalah pengenal_tipe, yang pada dasarnya merupakan sebuah pemegang tempat untuk tipe data yang masih belum ditetapkan dan akan diganti nanti oleh kompiler. Lihat bahwa Luas adalah nama fungsi. Sisi-sis x dan y adalah dua parameter dari fungsi Luas(). Variabel x merupakan panjang persegi-panjang dan y merupakan lebar dari persegi-panjang. Perhatikan bahwa T muncul sebelum Luas dan muncul juga sebelum x dan y pada kepala fungsi.


MEMANGGIL TEMPLATE FUNGSI
Template fungsi dipanggil dengan menyebutkan nama fungsi yang diikuti dengan tipe data aktual di dalam kurung siku, yang diikuti dengan daftar argumen di dalam kurung (). Hal ini diilustrasikan sebagai berikut:

nama_fungsi <tipe_aktual> (argumen_argumen);

Sebuah contoh pemanggilan template fungsi diberikan berikut:

int x = a, y = b;    //a dan b adalah argumen fungsi
Luas<int>(a,b);      //memanggil fungsi Luas

Sekarang, jika sisi-sisi dan Luas bertipe double, maka pemanggilan fungsi menjadi seperti berikut:

double x = A, y = B ; //A dan B adalah argumen fungsi
Luas<double>(a, b); //memanggil fungsi Luas

Program berikut mengilustrasikan kegunaan dari template fungsi yang menghitung luas dari persegi-panjang dengan sisi-sisi berupa nilai-nilai integer atau double.


Program 7.1 Mengilustrasikan pendefinisian dan pemanggilan template fungsi

#include <iostream>
using namespace std;

template <typename T> T Luas(T x, T y )         //template fungsi
{return x*y ;} // definisi

int main()
{
   int n = 4 , m = 3;
   double j = 6.5 , k = 4.1 ;

   cout<<"Luas 1 = "<<Luas<int>(n, m)<<"\t Luas 2 = "<< Luas<double>(j, k)<<endl;

   return 0;
}
KELUARAN
Luas 1 = 12      Luas 2 = 26.65


Pada program tersebut, T pada dasarnya pemegang tempat untuk tipe data. Program template dikompilasi hanya ketika tipe data aktual dari variabel disubstitusi untuk T. Pada program 7.1, pada pemanggilan Luas<int>(n, m), nilai balik dari fungsi Luas adalah int dan pada pemanggilan Luas<double>(n, m), nilai balik dari fungsi Luas adalah double.

Contoh lain disediakan pada program 7.2. Pada program ini, Anda tidak menyebutkan tipe data di dalam kurung siku pada saat pemanggilan fungsi. Kompiler, pada dasarnya, dapat mengetahui tipe data dari variabel yang ditanganinya karena tipe data telah disebutkan pada saat deklarasi variabel. Bahkan jika tipe <int> atau <double> tidak dicantumkan pada pemanggilan fungsi, maka kompiler akan mencari-tahu tipe data dari deklarasi variabel. Misalnya, ketika kompiler menjumpai int m, n;, maka T akan diganti dengan int. Misalnya, ketika kompiler menjumpai double j, k, maka T akan diganti dengan double dan kompiler akan menghasilkan spesialisasi template untuk nilai-nilai double. Selain itu, Anda bisa menggunakan sembarang pengenal yang sah untuk menggantikan T.

Berikut ini didefinisikan sebuah template fungsi untuk menentukan nilai maksimum dari dua nilai dengan deklarasi <class T> menggantikan <typename T>. Variabel-variabel dapat berupa nilai integer, titik-mengambang, atau karakter. Karakter juga memiliki nilai integral dari himpunan kode ASCII. Sebagai contoh, ‘A’ = 65 dan ‘B’ = 66, dan seterusnya. Definisi template fungsi diberikut berikut. Fungsi ini menentukan nilai terbesar dari dua nilai:

template <class T> T maks(T x, T y)
{return x > y ? x:y;}


Fungsi template didefinisikan di bawah main(), prototipe template atau deklarasi template diberikan di atas main(). Seperti dijelaskan untuk program 7.1, T adalah pengenal tipe, maks adalah nama fungsi, x dan y adalah dua parameter dari maks(). Perhatikan bahwa maks didahului oleh pengenal T dan dua parameter juga masing-masing diawali dengan pengenal T. Hal ini sangat mirip dengan deklarasi fungsi biasa kecuali untuk tipe data yang sekarang direpresentasikan oleh T. Program berikut mengilustrasikan deklarasi dari sebuah template fungsi yang mencari nilai terbesar dari dua variabel yang bisa bertipe int, double atau char.

Program 7.2 Mengilustrasikan template fungsi untuk mencari terbesar dari dua nilai

#include <iostream>
using namespace std;

template <class T> T maks(T x, T y)      //definisi fungsi
{return x>y ? x : y;}                    //tubuh fungsi

int main()
{
   int n = 64, m = 67 ;           //variabel-variabel int
   char ch1 = 'S' , ch2 = 'R';    //variabel-variabel char
   double D1 = 6.87, D2= 8.34;    //variabel-variabel double

   cout<<"maks(n,m)= "<<maks<int>(n,m)<<endl;

   cout<<"maks(ch1,ch2) = "<<maks<char>(ch1,ch2)<<endl;

   cout<<"maks(D1,D2) = "<<maks<double>(D1, D2)<< endl;

   return 0;
}
KELUARAN
maks(n,m)= 67
maks(ch1,ch2) = S
maks(D1,D2) = 8.34


Program berikut membuat sebuah template fungsi untuk fungsi Tukar yang menukar nilai dari dua variabel. Kuantitas-kuantitas yang terlibat dapat bertipe integer, double, char, atau string. String adalah objek dari kelas string (string C++) dan merupakan sebuah tipe data yang didefinisikan user. Fungsi yang sama dapat dipakai untuk semua tipe data.

Program 7.3 Mengilustrasikan template fungsi untuk menukar dua kuantitas

#include<iostream>
#include<string>
using namespace std;

template <class T>         //definsii template dari Tukar()
void Tukar(T &x , T &y) //nilai-nilai dilewatkan dengan referensi
{
   T temp;
   temp = x;
   x = y;
   y = temp;
}

void main()
{
   int n =60, m=30;
   char ch1= 'A', ch2 = 'D';
   double a = 2.45, b = 4.76;

   string S1 = "Selamat";  //S1 dan S2 adalah objek string
   string S2 = "Malam";           //tipenya adalah string

   Tukar<double>(a,b);
   Tukar<char>(ch1,ch2);

   Tukar<int>(n,m);
   Tukar<string>(S1,S2);  

   cout<<"a = "<<a<<"\tb = "<<b<<"\n";
   cout<<"ch1 = "<<ch1<<"\tch2 = "<<ch2<<endl;

   cout<<"n = "<<n<<" \tm = "<<m<<"\n";
   cout<<"S1 = "<<S1<<" , S2 = "<<S2<<endl;
}
KELUARAN
a = 4.76        b = 2.45
ch1 = D         ch2 = A
n = 30          m = 60
S1 = Malam,     S2 = Selamat
Sebelum implementasi fungsi Tukar(), nilai-nilai awal adalah a = 2.45, b = 4.76, ch1 = A, ch2 = D, n = 60, m = 30, dan string S1 = “Selamat” dan S2 = “Malam”. Nilai-nilai tersebut ditukar dengan mengimplementasikan fungsi Tukar(). Selain itu, perhatikan bahwa variabel-variabel dilewatkan dengan referensi pada deklarasi dari fungsi Tukar().



7.3 Template Fungsi dengan Array sebagai Parameter
Program berikut mengilustrasikan sebuah template fungsi untuk menampilkan isi dari sebuah array. Template fungsi Tampil() dideklarasikan sebagai berikut:

template <class T>
void Tampil(const T*A, unsigned int ukuran)

Di sini, ukuran mengimplikasikan jumlah atau banyaknya elemen di dalam array, T adalah nama dari pemegang tempat untuk tipe data dan A adalah nama array yang merupakan sebuah pointer konstan yang menunjuk ke elemen pertama dari array. Aplikasi dari kode ini diilustrasikan pada program berikut:

Program 7.4 Mengilustrasikan template fungsi untuk menampilkan isi array

#include <iostream>
using namespace std;

template <class T>
void Tampil(const T*A, unsigned int ukuran)     //deklarasi dan definisi fungsi
{
   for(int i =0 ; i<ukuran; i++ )
      cout<< A[i] <<" ";
  
   cout<<endl;
}

int main ()
{
   const int K = 6, M =15, J = 4;
   int Budi[J] = {20, 30, 40, 50}; //sebuah array integer

   //Berikut adalah sebuah array double
   double Kartini[K] = {4.5, 5.6, 7.8, 8.9, 1.2, 3.4};
  
   char Nama[M] = "John Kristof"; //sebuah string karakter

   Tampil(Budi, J);
   Tampil(Kartini , K);
   Tampil(Nama , M);

   return 0;
}
KELUARAN
20 30 40 50
4.5 5.6 7.8 8.9 1.2 3.4
J o h n   K r i s t o f


Berikut, program 7.5 akan diperluas untuk juga mencantumkan array yang memuat sejumlah string. Template fungsi yang sama, Tampil(), dipakai untuk menampilkan array integer, array double, array karakter, dan array string.

Program 7.5 Mengilustrasikan template fungsi untuk menampilkan isi array

#include <iostream>
using namespace std;

template <class T>
void Tampil(const T A[], unsigned int ukuran)   //deklarasi dan definisi fungsi
{
   for( int i =0 ; i<ukuran; i++ )
      cout<<A[i]<<" ";
  
   cout<<endl;
}

int main ()
{
   const int K = 6, M =15, J = 7, N = 4;
   int Budi[J] = {20,30, 40,50,60,70,80};

   char ch[N] = {'D', 'E', 'S', 'A'};

   double Kartini[K] = {4.5, 5.6, 7.8, 8.9, 1.2, 3.4};
  
   char* S[M] ={"Kristof", "John", "Martina", "Sandora", "Jelita"};

   Tampil(Budi, J);        //memanggil fungsi template
   Tampil(Kartini, K);
   Tampil(ch, N);
   Tampil(S, M);
  
   return 0;
}
KELUARAN
20 30 40 50 60 70 80
4.5 5.6 7.8 8.9 1.2 3.4
D E S A
Kristof John Martina Sandora Jelita


Pengurutan array cukup umum dalam pemrograman. Elemen-elemen array dapat bertipe int, double, atau char, yang kodenya hampir sama. Oleh karena itu, pada program berikut, sebuah template fungsi dikembangkan untuk mengurutkan elemen-elemen di dalam sebuah array dengan tatanan menaik.

Program 7.6 Mengilustrasikan template fungsi untuk mengurutkan isi array

#include <iostream>
using namespace std;

template <class T>   //template fungsi pengurutan
void UrutArray(T A[], const int n)
{
   for (int i = 0 ;i<n;i++)
   {
      for(int j=0;j<n-1;j++)
         if(A[j]>A[j+1])
            swap(A[j],A[j+1]);
   }
}

template <class T>
void Tampil(T A[], unsigned int ukuran)
{
   for (int i =0; i<ukuran; i++)
      cout<<A[i]<<" ";
   cout<<endl;
}

int main ()
{
   const int K = 6, J = 7;
   int ArrInteger[J] = {20, 30, 70, 80, 40, 50, 60};

   char ch [6] = {'B', 'A', 'N', 'G', 'S', 'A'};
   double ArrDouble[K] = {4.5, 5.6, 1.2, 7.8, 8.9, 3.2};

   UrutArray(ArrInteger, J);
   Tampil(ArrInteger, J);

   UrutArray(ArrDouble, K);
   Tampil<double>(ArrDouble, K);

   UrutArray(ch, 6);
   Tampil<char>(ch, 6);

   return 0;
}
KELUARAN
20 30 40 50 60 70 80
1.2 3.2 4.5 5.6 7.8 8.9
A A B G N S


TEMPLATE FUNGSI: MENUKAR SEJUMLAH TERTENTU ELEMEN ARRAY
Pada program 7.7, sebuah fungsi template Tukar() dikembangkan untuk menukar sejumlah tertentu elemen array dari dua array yang dapat bertipe int, double, char, atau lainnya. Nama generik dipakai sebagai nama kelas.

Program 7.7 Mengilustrasikan template fungsi untuk menampilkan isi array

#include <iostream>
using namespace std;

template <class generik>   //deklarasi dan definisi dari Tukar
void Tukar (generik x[ ], generik y[ ], int m)
{
   generik temp ; // type identifier is generik in place of T
   for (int i = 0; i<m;i++)
   {
      temp = x[i];
      x[i] = y[i];
      y[i] = temp ;
   }
} //akhir dari template fungsi

void main()
{
   double Budi[] = {11.1, 12.2, 13.3, 14.4 ,15.5};
   double Wati[] = {30.5, 31.1, 32.2, 33.3, 34.4};
  
   char Ch[] = {'B', 'A', 'N', 'G', 'S', 'A'};
   char Kh[] = {'S', 'O', 'N', 'T', 'A', 'K'};
  
   int K[5] = {1, 2, 3, 4, 5};
   int M[5] = {50, 60, 70, 80, 90};

   cout<<"Sebelum penukaran array:\n";
   cout<<"Budi\tWati\tCh\tKh\tK\t M"<<endl;
   for  (int k = 0; k <5; k++)
      cout <<Budi[k] <<"\t"<<Wati[k]<<"\t"<<Ch[k]<<"\t"<<Kh[k] <<"\t"
              <<K[k]<<"\t"<<M[k] <<endl;
  
   Tukar(Budi, Wati, 1);
   Tukar(K, M, 3);
   Tukar(Ch, Kh, 5) ;

   cout<<"Setelah penukaran array:\n";
   cout<<"Budi\tWati\tCh\tKh\tK\tM "<<endl;
   for (int j = 0; j <5; j++)
   cout <<Budi[j] <<"\t"<<Wati[j]<<"\t"<<Ch[j]<<"\t"<<Kh[j]<< "\t"
        <<K[j]<<"\t"<<M[j]<<endl;
}
KELUARAN
Sebelum penukaran array:
Budi    Wati    Ch      Kh      K        M
11.1    30.5    B       S       1       50
12.2    31.1    A       O       2       60
13.3    32.2    N       N       3       70
14.4    33.3    G       T       4       80
15.5    34.4    S       A       5       90

Setelah penukaran array:
Budi    Wati    Ch      Kh      K       M
30.5    11.1    S       B       50      1
12.2    31.1    O       A       60      2
13.3    32.2    N       N       70      3
14.4    33.3    T       G       4       80
15.5    34.4    A       S       5       90

Seperti yang ditetapkan di dalam program antara array Budi dan array Wati hanya ada satu elemen yang ditukar, antara Ch dan Kh kelima elemen ditukar dan antara K dan M hanya 3 elemen yang ditukar.



7.4 Template Fungsi dengan Pelbagai Tipe Argumen
Sampai sekarang, Anda telah belajar sejumlah template fungsi yang hanya melibatkan satu tipe data dari variabel. Sebagai contoh, semua parameter fungsi hanya integer atau hanya double atau hanya char. Nilai baliknya juga bertipe sama. Tetapi, ada beberapa situasi dimana parameter-parameter fungsi memiliki tipe data yang berbeda. Ilustrasi dari deklarasi template untuk kasus semacam itu diberikan berikut. Fungsi template memilih nilai terbesar dari dua nilai yang bisa jadi tidak bertipe data sama. Oleh karena itu, dua pemegang tempat dideklarasikan dengan nama kelas.

template <class T, class E>
T maks(T x , E y)
{return x > y ? x : y ;}

Pada deklarasi ini, keluaran akan beripe data T. Jika keluaran diinginkan bertipe E, maka Anda bisa mendeklarasikannya menjadi:

template<class T, class E>
E maks(T x , E y)
{return x > y ? x : y ;)}

Program berikut memberikan sebuah ilustrasi dari template fungsi tersebut untuk mencari nilai terbesar dari dua nilai, dimana kedua nilai tersebut dapat berbeda tipe data.

Program 7.8 Mengilustrasikan template fungsi untuk pelbagai tipe data

#include <iostream>
using namespace std;
template <class T , class E> E maks(T x, E y)
{
   return x>y ? x : y;
}

int main()
{
   int n = 88 ;
   double m = 80.4 ;

   int ch1 = 67 ;
   char ch2 = 'A';

   double D1 = 76.87, D2= 90.3;
  
   cout<<"maks(n, m)= "<<maks(n,m)<<endl;
   cout<<"maks(ch1,ch2) = "<<maks(ch1,ch2)<<endl;

   cout<<"maks(D1,D2) = "<<maks(D1, D2)<< endl;
   cout<<"maks(n,D2) = "<<maks(n,D2)<<endl;

   return 0;
}
KELUARAN
maks(n, m)= 88
maks(ch1,ch2) = C
maks(D1,D2) = 90.3
maks(n,D2) = 90.3



7.5 Membebani (Mengoverload) Template Fungsi
Pembebanan template fungsi sama dengan dengan pembebanan fungsi biasa. Pada pembebanan fungsi, nama fungsi sama sedangkan argumen-argumennya berbeda dalam jumlah dan atau tipe. Program berikut mengilustrasikan template fungsi yang dibebani.

Program 7.9 Mengilustrasikan pembebanan template fungsi dengan parameter-parameter satu tipe data

#include <iostream>
using namespace std;

template <class T>
T Perkalian(T x, T y)
{return x*y;}

template <class T>
T Perkalian( T x, T y, T z)
{return x*y*z;}

int main ()
{
   int a (2), b(3), c(4);
   double A(2.0), B(5.5), C(1.5);

   cout<<"Perkalian(A, B, C) = "<<Perkalian(A, B, C)<<endl;;
   cout<<"Perkalian(A, B) = "<<Perkalian(A, B)<<endl;

   cout<<"Perkalian(a, b, c) = "<<Perkalian(a, b, c)<<endl;

   return 0;
}
KELUARAN
Perkalian(A, B, C) = 16.5
Perkalian(A, B) = 11
Perkalian(a, b, c) = 24


Setiap fungsi pada program tersebut memiliki satu jenis tipe data variabel. Baik itu int, atau double. Pada program berikut, Anda akan memiliki template fungsi terbebani yang memiliki beberapa tipe data argumen yang berbeda.

Program 7.10 Mengilustrasikan pembebanan template fungsi dengan parameter-parameter bertipe data yang berbeda

#include <iostream>
using namespace std;

template <class T, class U>
U Perkalian (T x, U y)
{return x*y;}

template <class T, class S, class U>
S Perkalian (T x, S y, U z)
{return x*y*z;}

int main ()
{
   int a(1);
   double B(1.5);
   char Ch('D');

   cout<<"Perkalian(a, B, Ch) = "<<Perkalian(a, B, Ch)<<endl;
   cout<<"Perkalian(a, B) = "<<Perkalian(a, B)<<endl;

   cout<<"Perkalian('A', 4.5, 6) = "<<Perkalian('A', 4.5, 6)<<endl;

   return 0;
}
KELUARAN
Perkalian(a, B, Ch) = 102
Perkalian(a, B) = 1.5
Perkalian('A', 4.5, 6) = 1755



7.6 Template Kelas
Anda telah memiliki pengalaman yang berkaitan dengan template fungsi. Tipe-tipe data yang berbeda dapat dipakai untuk evaluasi fungsi. Template kelas memiliki watak yang sama. Objek-objek kelas yang memiliki pelbagai tipe data yang berbeda dapat menggunakan template kelas yang sama. Sebuah template kelas dideklarasikan sebagai berikut:

template <class pengenal_tipe> class pengenal_tipe_untuk_kelas

Sebagai contoh, template kelas untuk Kubik dideklarasikan berikut:

template <class T> class Kubik

Di sini, Kubik adalah nama kelas sedangkan T adalah nama dari pemegang tempat untuk tipe data. Anda dapat menggunakan sembarang nama yang valid untuk T. Selain itu, kapanpun variabel dideklarasikan di dalam kelas, ia harus dideklarasikan dengan diawali oleh pengenal tipe T. Objek kelas dideklarasikan sebagai berikut:

nama_kelas <type> nama_objek;

Program berikut merupakan sebuah template kelas untuk kelas Kubik yang menghitung luas permukaan dan volume dari sebuah tubuh prismatis persegi-panjang. Dimensi-dimensi dapat berupa int, float, double, long, atau short. Pada program ini, fungsi-fungsi anggota didefinisikan di dalam kelas.

Program 7.11 Mengilustrasikan template kelas dengan fungsi-fungsi anggota didefinisikan di dalam kelas

#include <iostream>
using namespace std;

template <class T>
class Kubik {
   T x , y , z ; //variabel x , y, z bertipe data sama

   public:
      Kubik(T L, T W, T H)
      {
         x = L; y = W; z = H;
      }
     
      T luas_permukaan()
      {
         return 2*(x*y +y*z +z*x);
      }

      T volume() {
         return x*y*z;
      }
};
// akhir dari kelas

int main()
{
   Kubik<int> C1(3, 8, 5);        //dimensi-dimensi bertipe int
   Kubik<double> C2(3.5, 5.5, 4.5) ;     //dimensi-dimensi bertipe double

   cout<<"Volume dari C1 = "<<C1.volume()<<"\n";
   cout<<"Volume dari C2 = "<<C2.volume()<<"\n";

   cout<<"Luas permukaan dari C1 = "<<C1.luas_permukaan()<<"\n";
   cout<<"Luas permukaan dari C2 = "<<C2.luas_permukaan()<<"\n";

   return 0 ;
}
KELUARAN
Volume dari C1 = 120
Volume dari C2 = 86.625
Luas permukaan dari C1 = 158
Luas permukaan dari C2 = 119.5


MENDEFINISIKAN TEMPLATE FUNGSI DI LUAR TEMPLATE KELAS
Pada program tersebut, semua fungsi didefinisikan di dalam template kelas. Kode untuk mendefinisikan sebuah template fungsi di luat template kelas diilustrasikan sebagai berikut:

T pengenal_kelas <T>::pengenal_fungsi (pengenal_tipe parameter1, … )
{stamen_statemen;}

Sebagai ilustrasi untuk ini, deklarasi dari fungsi volume akan diberikan pada program 7.12 yang diilustrasikan dengan kode berikut:

template <class T>
T Kubik <T>::volume()
{return x*y*z ;}

Program 7.12 Mengilustrasikan template kelas dengan fungsi-fungsi anggota didefinisikan di luar kelas

#include <iostream>
using namespace std;

template <class T>   //deklarasi dari template kelas
class Kubik {
   public:
      T x , y , z ;
      Kubik (T L, T W, T H){x = L; y = W; z = H ;}     //konstruktor
  
      T luas_permukaan();  //prototipe fungsi di dalam tubuh kelas
      T volume();          //prototipe fungsi di dalam tubuh kelas
}; //akhir kelas

template <class T> //definisi fungsi
T Kubik <T>::luas_permukaan()
{
   return 2*(x*y +y*z +z*x);
}

template <class T > //definisi fungsi
T Kubik <T>::volume()
{
   return x*y*z;
}

int main()
{
   Kubik<int> C1(5,6,4);          //Objek dengan dimensi-dimensi int
   Kubik<double> C2(2.2,3.5,4.5) ; //Objek dengan dimensi-dimensi
                                  //dalam nilai-nilai titik-mengambang

   cout<<"Volume dari C1 = "<<C1.volume()<<"\n";
   cout<<"Volume dari C2 = "<<C2.volume()<<"\n";

   cout<<"Luas permukaan dari C1 = "<<C1.luas_permukaan()<<"\n";
   cout<<"Luas permukaan dari C2 = "<<C2.luas_permukaan()<<"\n";

   return 0 ;
}
KELUARAN
Volume dari C1 = 120
Volume dari C2 = 34.65
Luas permukaan dari C1 = 148
Luas permukaan dari C2 = 66.7


Objek kelas C1 memiliki tipa data integer sedangkan objek C2 memiliki tipe data double. Template kelas memproses kedua tipe data.

Program berikut juga akan berkaitan dengan template kelas, dimana semua prototipe fungsi termasuk fungsi konstruktor dideklarasikan di dalam template kelas dan didefinisikan di luar template kelas.

Program 7.13 Mengilustrasikan template kelas dengan fungsi-fungsi anggota termasuk fungsi konstruktor didefinisikan di luar kelas

#include <iostream>
using namespace std;

template <class T>   //deklarasi dari template kelas
class Kubik {
   public:
      Kubik(T, T, T);             //prototipe konstruktor
  
      T luas_permukaan();  //prototipe fungsi di dalam tubuh kelas
      T volume();          //prototipe fungsi di dalam tubuh kelas

   private:
      T x, y, z;
}; //akhir kelas

template <class T>         //definisi fungsi konstruktor
Kubik <T>::Kubik <T> (T L, T W, T H)
{
   x = L; y= W; z=H;
}

template <class T>         //definisi fungsi
T Kubik <T>::luas_permukaan()
{
   return 2*(x*y +y*z +z*x);
}

template <class T >        //definisi fungsi
T Kubik <T>::volume()
{
   return x*y*z;
}

int main()
{
   Kubik<int> C1(5,6,4);          //Objek dengan dimensi-dimensi int
   Kubik<double> C2(2.2,3.5,4.5) ; //Objek dengan dimensi-dimensi
                                  //dalam nilai-nilai titik-mengambang

   cout<<"Volume dari C1 = "<<C1.volume()<<"\n";
   cout<<"Volume dari C2 = "<<C2.volume()<<"\n";

   cout<<"Luas permukaan dari C1 = "<<C1.luas_permukaan()<<"\n";
   cout<<"Luas permukaan dari C2 = "<<C2.luas_permukaan()<<"\n";

   return 0 ;
}
KELUARAN
Volume dari C1 = 120
Volume dari C2 = 34.65
Luas permukaan dari C1 = 148
Luas permukaan dari C2 = 66.7



7.7 Template Fungsi Friend
Deklarasi atas template fungsi friend di dalam kelas sama dengan deklarasi fungsi tak-template. Definisi dari fungsi friend dilakukan di luara kelas tanpa adanya operator resolusi skop.

Program berikut mengilustrasikan deklarasi dari sebuah template fungsi friend dengan nama Luas di dalam suatu template kelas dengan nama Rekt yang menangani persegi-panjang. Template kelas memuat data private, yaitu sisi-sisi persegi-panjang, fungsi konstruktor, dan deklarasi dari fungsi friend yang didefinisikan di luar kelas. Objek kelas merupakan argumen dari fungsi friend.

Program 7.14 Mengilustrasikan template fungsi friend

#include <iostream>
using namespace std;

template <class T>
class Rekt {
   friend T Luas(const Rekt &R); //deklarasi dari template fungsi friend

   private:
      T x; // x dan y adalah sisi-sisi dari persegi-panjang
      T y;

   public:
      Rekt(T A, T B) {x = A , y = B; } //konstruktor
}; //akhir dari template kelas

template <class T> //definisi dari fungsi friend
T Luas(const Rekt <T> &R)
{
   return R.x* R.y ;
} // R adalah sebuah objek

int main ()
{
   Rekt<int> kuRekt(6, 2); // kuRekt adalah sebuah objek dari Rekt

   cout<<"Luas = "<<Luas(kuRekt)<<endl;

   return 0;
}
KELUARAN
Luas = 12


Program 7.15 Mengilustrasikan template fungsi friend di dalam kelas dengan multi tipe data

#include <iostream>
using namespace std;

template <class T, class U> //template kelas dengan multi tipe data
class Rekt
{
   private:
      T x;
      U y;

   public:
      Rekt (T A, U B) {x = A, y = B;}
      friend U Luas (const Rekt &R); //template fungsi friend
};

template <class T, class U>
U Perkalian(T x, U y)
{
   return x*y;
}

template <class T, class S, class U>
S Perkalian (T x, S y, U z)
{
   return x*y*z;
}

int main ()
{
   int a(1);
   double B(1.5);
   char Ch('D');

   cout<<"Perkalian(a, B, Ch) = "<<Perkalian(a, B, Ch)<<endl;;
   cout<<"Perkalian(a, B) = "<<Perkalian(a, B)<<endl;
   cout <<"Perkalian('A', 4.5, 6) = "<<Perkalian('A', 4.5, 6)<<endl;

   return 0;
}
KELUARAN
Perkalian(a, B, Ch) = 102
Perkalian(a, B) = 1.5
Perkalian('A', 4.5, 6) = 1755


Program berikut merupakan contoh lain dari sebuah template fungsi friend di dalam sebuah template kelas.

Program 7.16 Mengilustrasikan contoh lain dari template fungsi friend di dalam kelas

#include <iostream>
using namespace std;

template <class T> //deklarasi tipe
class Kubik { //awal dari template kelas
   private:
      T x, y, z;

   public:
      Kubik (T, T, T); //prototipe konstruktor
      T luas_permukaan();
      T volume();

      //template fungsi friend
      friend T biayaLukis(T, const Kubik <T> &C);
}; //akhir dari kelas Kubik

template <class T> //definisi dari konstruktor di luar kelas
Kubik <T> :: Kubik<T>(T L, T W, T H) {
   x = L; y = W; z = H;
}

template <class T>   //definisi dari fungsi luas permukaan
T Kubik <T>::luas_permukaan()
{
   return 2*(x*y +y*z +z*x);
}

template <class T> //definisi dari fungsi volume
T Kubik <T>::volume()
{
   return x*y*z;
}

//berikut adalah definisi dari template fungsi friend
template <class T >
T biayaLukis(T Rho, Kubik<T> &C)
{
   return Rho * C.luas_permukaan();
}

int main()
{
   Kubik<int> C1(4, 5, 6) ;
   Kubik<double> C2(2.5, 3.0, 4.0);

   int D1 = 3;
   double D2 = 2.0;

   cout<<"Volume dari C1 = "<<C1.volume()<<"\n";
   cout<<"Volume dari C2 = "<<C2.volume()<<"\n";

   cout<<"Luas permukaan dari C1 = "<<C1.luas_permukaan()<<"\n";
   cout<<"Luas permukaan dari C2 = "<<C2.luas_permukaan()<<"\n";

   cout<<"Biaya melukis P1 = "<<biayaLukis(D1, C1)<<"\n";
   cout<<"Biaya melukis P2 = "<<biayaLukis(D2, C2)<<"\n";

   return 0 ;
}
KELUARAN
Volume dari C1 = 120
Volume dari C2 = 30
Luas permukaan dari C1 = 148
Luas permukaan dari C2 = 59
Biaya melukis P1 = 444
Biaya melukis P2 = 118



7.8 Template Kelas Friend
Proses pendeklarasian template kelas friend sama dengan kelas tak-template dengan pengecualian untuk tipe data dari variabel-variabel yang terlibat. Hal ini diilustrasikan pada program berikut dimana di dalamnya template kelas friend dideklarasikan dengan nama lukis. Kelas lukis dideklarasikan sebagai friend terhadap kelas Kubik. Deklarasi dari kelas lukis diilustrasikan berikut:

template <class U > class lukis;

Di dalam tubuh dari kelas Kubik, kelas lukis dideklarasikan dengan

friend class lukis;

Program 7.17 Mengilustrasikan template kelas friend

template <class U> class lukis;
#include <iostream>
using namespace std;

template <class T>
class Kubik {
   friend class lukis;            //deklarasi dari kelas lukis sebagai friend

   public:
      Kubik ( T, T, T);           //prototipe konstruktor dari kelas Kubik
      T luas_permukaan();  //prototipe dari luas_permukaan() dan volume()
      T volume();

   private:
      T x, y, z; // x , y and z are of same type
}; //akhir dari kelas Kubik

template <class T>         //definisi konstruktor untuk kelas Kubik
Kubik <T> :: Kubik<T>(T L, T W, T H) {
   x = L; y = W; z = H;
}

template <class T>         //definisi dari fungsi luas_permukaan()
T Kubik <T>::luas_permukaan()
{
   return 2*(x*y +y*z +z*x);
}

template <class T>         //definisi dari fungsi volume()
T Kubik <T>::volume()
{
   return x*y*z;
}

template <class U> //kelas lukis
class lukis { //definisi dari kelas lukis
   private:
      U Rho;

   public:
      lukis(U);            //prototipe dari konstruktor
      lukis(){Rho =2;};    //konstruktor default

      U biaya(U Rho,U luas_permukaan ) //definisi dari fungsi biaya()
      {
         U CP; // CP = biaya lukis
         CP = Rho* luas_permukaan ;
         return CP;
      }
}; //akhir dari kelas lukis

template <class U> //konstruktor untuk kelas lukis
lukis<U>::lukis<U>(U D) {
   Rho = D;
}

int main()
{
   Kubik<int> C1(4, 5, 6);
   Kubik<int> C2(2, 3, 4);

   lukis<int> P1;
   lukis<int> P2;

   int R1 =2;
   int R2 = 3;

   cout<<"Volume dari C1 = "<<C1.volume()<<"\n";
   cout<<"Volume dari C2 = "<<C2.volume()<<"\n";

   cout<<"Luas permukaan dari C1 = "<<C1.luas_permukaan()<<"\n";
   cout<<"Luas permukaan dari C2 = "<<C2.luas_permukaan()<<"\n";

   cout<<"Biaya melukis P1 = "<<P1.biaya(7, C1.luas_permukaan())<< "\n";
   cout<<"Biaya melukis P2 = "<< P2.biaya (7, C2.luas_permukaan())<<"\n";

   return 0 ;
}
KELUARAN
Volume dari C1 = 120
Volume dari C2 = 24
Luas permukaan dari C1 = 148
Luas permukaan dari C2 = 52
Biaya melukis P1 = 1036
Biaya melukis P2 = 364



7.9 Template Kelas untuk Variabel-Variabel Kompleks
File header <complex> memuat kelas template untuk memanipulasi variabel-variabel kompleks. Program berikut mengilustrasikan sejumlah operasi aritmatika pada variabel-varaibel kompleks dengan mencantumkan file header ini di dalam program. Sebuah variabel kompleks terdiri-dari sepasang nilai, yaitu nilai riil dan nilai imajiner.

Program 7.18 Mengilustrasikan template kelas friend

#include<iostream>
#include<complex>
using namespace std;

int main ()
{
   complex<double> a(4.5, 5.5) ;
   complex<int> b(2,3) ;

   complex<int> g(3,4) ;
   complex<double> e(1.4, 3.4);

   complex<double> C = a + e ;
   complex<int>D = g - b;

   complex<int> Perkalian = b*b ;

   cout<<"a = "<<a<<"\t"<<"b = "<<b<<"\n";
   cout<<"C= "<<C<<"\t"<<"D = "<<D<<"\n";

   cout<<"Perkalian b*b = "<<Perkalian<<endl;

   return 0;
}
KELUARAN
a = (4.5,5.5)   b = (2,3)
C= (5.9,8.9)    D = (1,1)
Perkalian b*b = (-5,12)

LATIHAN
1.       Apa itu template fungsi?
2.       Apa itu template kelas?
3.       Apa yang Anda pahami tentang pemrograman generik?
4.       Bagaimana Anda mendeklarasikan sebuah template fungsi?
5.       Bagaimana Anda mendeklarasikan sebuah template fungsi untuk menampilkan isi dari sebuah array?
6.       Bagaimana Anda mendefinisikan sebuah template fungsi ketika semua parameternya bertipe data sama?
7.       Apa itu spesialisasi template fungsi?
8.       Apa itu spesialisasi template kelas?
9.       Bagaimana Anda mendeklarasikan template fungsi yang melibatkan lebih dari satu tipe data pada parameter-parameternya?
10.    Dapatkah sebuah template fungsi dibebani (dioverload) Jika bisa, bagaimana hal itu dilakukan?
11.    Bagaimana Anda mendefinisikan sebuah template fungsi friend untuk fungsi-fungsi yang memiliki lebih dari satu tipe data pada parameter-parameternya?
12.    Bagaimana Anda mendefinisikan sebuah template kelas untuk data objek dengan multi tipe data?
13.    Berikan sebuah contoh deklarasi dari sebuah template fungsi friend di dalam sebuah template kelas.
14.    Bagaimana Anda mendeklarasikan sebuah template kelas sebagai friend bagai template kelas lain?
15.    Tulislah sebuah program yang menggunakan template fungsi untuk menghitung luas dari lingkaran. Tulis juga program pengujinya.
16.    Tulislah sebuah program yang menggunakan template fungsi untuk menukar elemen-elemen dari dua array, dimana elemen-elemen array dapat berupa karakter-karakter maupun nilai-nilai double.
17.    Tulislah sebuah program yang menggunakan template fungsi untuk mencari dan menampilkan nilai terkecil dari dua nilai, dimana kedua nilai tersebut dapat berupa integer, nilai titik-mengambang, atau karakter.














No comments: