• Tidak ada hasil yang ditemukan

Apakah kita harus menggunakan fitur c++/cx pada semua tempat?

N/A
N/A
Protected

Academic year: 2021

Membagikan "Apakah kita harus menggunakan fitur c++/cx pada semua tempat?"

Copied!
24
0
0

Teks penuh

(1)

WinRT berdiri diatas COM yang tetap memiliki mekanisme reference counting. Tetapi WinRT tidaklah memiliki kerumitan yang dimiliki oleh COM sebelumnya. Hal ini dimungkinkan dengan c++/cx yang merupkan penambahan fitur terhadap terhadap bahasa C++. Penambahan tersebut memberikan kita kemudahan untuk mengkonsumsi dan membuat tipe WinRT kita sendiri.

C++/CX

Penambahan yang diberikan kepada c++/cx meliputi 3 area. Berikut table lengkap yang akan kita bahas pada bagian berikutnya.

Untuk Allocation dibelakang layar COM menggunakan reference counting tetapi kita dengan

menggunakan c++/cx tidak perlu lagi terlibat langsung untuk hal ini. Kita tidak perlu melakukan release atau delete secara manual. Secara otomatis dilakukan oleh runtime.

Kapan menggunakan c++/cx ?

Apakah kita harus menggunakan fitur c++/cx pada semua tempat ? Jawabannya tentu saja tidak. Perhatikan gambar berikut

(2)

Kita tidak perlu membuat semua kelas kita dengan c++/cx. Kita hanya perlu menggunakannya pada saat kita akan berkomunikasi dengan WinRT. Untuk lingkungan internal maka kita dapat menggunakan ISO C++. Jangan beranggapan bahwa kita akan meninggalkan ISO C++ sepenuhnya dan beralih ke CX. Hal ini merupakan tanggapan yang salah. Anda tidak perlu merubah semua code base anda ke c++/cx agar dapat digunakan pada metrostyle.

Dengan C++/CX kita tidak perlu lagi memanggil Windows API yang kita kenal dengan bahasa C dan COM yang dulu. Tetapi dengan tipe WinRT yang memiliki konsep OOP, interface, event, delegate, class. Kita dapat menikmati segala kemewahan yang kita miliki dari Object Oriented.

Anda juga dapat mengekspose library sehingga dapat dikonsumsi oleh bahasa lain dengan C++/CX. Kita menamakannya WinRT component. Component ini dapat dikonsumsi oleh c#, vb, dan js.

Bahasa

Lifetime Management

Pada contoh program yang sebelumnya jika anda memperhatikan anda akan menemukan simbol yang berbeda yaitu ^ (dibaca Hat).

(3)

Handle ^ (hat) merupakan pointer ke WinRT dimana compiler secara otomatis melakukan reference counting. Perhatikan deklarasi dari CameraCaptureUI.

Kedua deklarasi diatas sebenarnya sama. dengan keyword auto compiler akan menterjemahkan tipe secara otomatis. Ini merupakan fitur dari c++11 yang membuat c++ menjadi modern. Anda dapat melihat pada tutorial berikut.

Modern::C++ (Not Your GrandDaddy) C++

ref new digunakan untuk melakukan instansiasi dan mengaktifasi WinRT. dengan ref new maka yang dikembalikan adalah ^ dan bukan *. Untuk melakukan de-reference masih tetap menggunakan dengan cara yang sama menggunakan -> (arrow). Jadi tidak banyak berbeda sebenarnya dengan ISO c++. Jika kita ingin membuat analogi maka kita bisa dapa menganggap bahwa ^ merupakan smart pointer. Anda mungkin sudah biasa menggunakan CCOMPtr dari ATL library untuk mengatur AddRef dan Release otomatis. Hanya saja sekarang kita tidak lagi menggunakannya secara langsung tetapi sudah di generate oleh compiler. Optimasi juga dilakukan oleh kompiler sehingga performance nya sangat baik.

Runtime Class

Jika kita ingin membuat suatu component yang ingin diakses oleh bahasa lain, maka kita mendefinisikannya dengan sebagai berikut.

Perhatikan bahwa untuk public method kita harus menggunakan tipe WinRT. Pada contoh diatas kita memiliki Constructor person yang melewatkan parameter dengan tipe String^ yang merupakan tipe WinRT.

Untuk method yang private/internal kita dapat menggunakan tipe c++ yang mana saja. Hal ini dapat dilakukan karena akses private dan internal tidak dapat diakses dari luar assembly tersebut, sehingga tidak ada kemungkinan untuk keluar dari ABI (Abstract Binary Interface). Pada contoh diatas kita melihat method SetPassword dengan akses internal melewatkan parameter wstring.

(4)

Sekarang saya akan melakukan demo untuk menjelaskan konsep yang telah kita pelajari sebelumnya mengenai (^)hat, reference counting dan kelas.

Setup Project

Seperti biasa buat project c++ MetroStyle terlebih dahulu. Letakkan satu Button dan satu TextBox pada Page tersebut. Perbesar ukuran dari TextBlock.

Berikan nama TextBlock tersebut karena kita akan melewatkannya sebagai parameter kelas. Hapus nilai default valu dari TextBlock tersebut

(5)

Perbesar ukuran dari text yang akan ditampilkan pada TextBlock, cara yang paling mudah untuk mencari property ukuran font adalah dengan mengetikkan font pada search. Ubah ukurannya menjadi 16px

Double click button untuk membuat event handler pada button tersebut. Biarkan saja kosong untuk sekarang.

Membuat Kelas

Buat kelas baru dengan mengklik kanan pada project anda dan memilih Add -> Class

(6)

Anda akan diarahkan untuk memberikan nama pada kelas tersebut dengan wizard. Beri nama Person pada kelas tersebut maka Visual Studio akan mengenerate dua file yaitu header .h dan implementasi .cpp

(7)

KIta perhatikan bahwa pada solution explorer kita telah memiliki tambahan 2 file yaitu Person.h dan Person.cpp

(8)

Kita membuat deklarasi kelas ref class dan sealed untuk WinRT type. Pada constructor kita melewatkan object TextBlock. Perhatikan bahwa kita menggunakan Hat untuk merujuk kepada object tersebut. Kita juga membuat private variable dengan tipe TextBlock untuk menyimpan reference terhadap txt. Kita juga membuat satu public method untuk menampilkan pesan.

Sekarang kita akan mengimplementasikan Person pada Person.cpp

Kita akan membuktikan apakah benar memory tersebut akan di release dengan melakukan invoke terhadap destructor secara otomatis. Anda juga sebenarnya dapat mengimplementasikan constructor dan destructor secara inline pada header Person.h.

Kita sekarang akan menggunakan kelas tersebut pada kelas BlankPage.xaml.cpp. Jangan lupa untuk menginclude Person.h.

(9)

Sekarang kita akan mengisi implementasi dari event click handler pada button tersebut.

Kita melewatkan object TextBlock txtDisplay. Kita juga menggunakan ref new untuk instansiasi kelas dan mereferencenya dengan Person^. Sekarang kita tinggal menjalankannya saja seperti biasa dengan F5.

Anda dapat melihat bahwa secara otomatis destructor akan dipanggil ketika object tersebut keluar dari scope method button click. Dengan demikian kita tidak takut lagi dengan memory leak.

Interface

Kita juga mendapatkan tambahan fitur interface. Kita tahu bahwa konsep programming to interface adalah salah satu practice yang dapat menuntun kita membuat aplikasi yang flexible dan mudah menangani perubahan. Konsep ini juga digunakan untuk membuat design pattern.

Interface hanya berisi method saja dan tidak memiliki variable. secara default semua method yang di deklarasikan di dalam interface adalah public. Berikut cara mendeklarasikannya.

Kita tidak perlu lagi menyebutkan virtual dan =0 untuk method tersebut. Karena semuanya sudah secara implicit dilakukan oleh kompiler.

(10)

Semua method yang ada pada IAnimal akan diturunkan ke IFeline. Sekarang kita akan membuat kelas Cat yang mengimplementasikan IFeline. Begini cara deklarasi dari header file Cat tersebut. Anda dapat mengimplementasikannya sendiri.

Setelah anda membuat implemtasi dari kelas tersebut maka kita dapat menggunakannya dengan cara merujuknya dari interfacenya dengan cara berikut.

Dengan interface kita dapat mengurangi coupling terhadap component lain. Property

Mungkin beberapa diantara dari programmer c++ sudah familiar dengan konsep property dari c# atau visual basic. Pada iso c++ kita tidak memiliki konsep property. Jika kita menerapkan konsep enkapsulasi maka kita akan membuat data menjadi private dan membuat setter dan getter untuk mengakses data tersebut. Property merupakan salah satu cara yang lebih baik untuk mengimplementasikan hal tersebut. Dengan property kita seolah oleh memiliki data field tetapi kita tidak akses langsung. Hal ini membuat kita dapat menyembunyikan detail implementasi dari kelas kita. Berikut ini adalah cara yang mudah untuk membuat property.

(11)

Pada contoh diatas kita membuat property Name yang secara otomatis compiler akan membuat data member dengan akses private dan setter dan getter. Hal ini dibuat untuk mempermudah kita sehingga kita tidak perlu repot mengimplementasikan hal yang trivial seperti berikut. Secara otomatis kompiler akan membuatnya untuk kita.

Hal diatas baru bermanfaat jika kita ingin memiliki logic atau validasi yang ingin kita lakukan pada property. Kita dapat mendefinisikan sebagai berikut.

(12)

Pada property yang kita definisikan sendiri kita membuat setter (set())dan getter (get()). Pada contoh ini kita juga membuat member data private. Kita bisa saja tidak membuatnya jika memang tidak

dibutuhkan. Anda juga tidak dapat hanya mengimplementasikan setter saja atau getter saja, tidak ada kewajiban anda harus mengimplementasikan keduanya.

Cara menggunakannya adalah sama jika kita ingin memanggil member data field dari suatu kelas seperti berikut.

Delegates

Kita dapat menganggap delegate adalah pointer ke function. Tetapi delegate adalah type safe dan dapat dalam konteks ABI. Delegate merupakan tipe yang merujuk kepada operasi dan bukan kepada object. Karena delegate adalah tipe maka kita dapat menginstansiasinya seperti yang kita lakukan terhadap kelas. Hal ini berguna jika kita ingin mengimplementasikan event atau callback. Dengan demikian kita dapat membuat program yang loose couple tidak terikat langsung kepada object tetapi hanya terhadap

(13)

operasi tertentu. Berikut cara mendeklarasikannya, anda dapat melakukan deklarasi sama seperti function.

Cara melakukan instansiasi terhadap delegate sama dengan yang kita lakukan dengan kelas. Kita menggunakan ref new seperti berikut.

Pada contoh di atas kita membuat delegate yang merujuk fungsi yang kita definisikan dengan lambda. Lambda merupakan fitur baru pada c++11. Anda dapat melihat daftar fitur baru yang ada pada c++11 pada tutorial saya sebelumnya.

Modern::C++ (Not Your GrandDaddy) C++

Selain dengan membuat dengan anonymous function atau lambda kita juga dapat melakukan

assignment terhadap delegate tersebut ke free function (fungsi yang tidak terikat kepada kelas tertentu) atau ke method (fungsi yang terikat pada kelas tertentu).

Berikut contoh dengan menggunakan free function.

Jika anda memiliki fungsi dengan deklarasi sebagai berikut ini sebagai free function anda dapat meng-assign langsung ke delegate.

Kita melakukan instansiasi delegate dengan cara sebagai berikut

(14)

maka kita dapat melakukan instansiasi delegate dengan cara sebagai berikut.

Setelah anda selesai dengan melakukan inisialisasi terhadap delegate maka anda tinggal memanggilnya sama seperti cara anda memanggil fungsi sebagai berikut.

Event

Anda bisa mengangap bahwa event adalah property dengan tipe delegate. Tetapi operasi yang kita lakukan terhadap event bukan set dan get tetapi menambah(add), menghapus(remove) dan

mengeksekusi(raise) callback. Tipe yang digunakan untuk operasi terhadap event tersebut adalah tipe delegate. Berikut cara deklarasi dari event tersebut.

Dengan cara diatas maka secara otomatis operasi add, remove dan raise akan dibuat oleh kompiler untuk kita. Anda dapat membuat nya sendiri jika dibutuhkan.

Berikut cara yang kita lakukan untuk melakukan registrasi terhadap event tersebut. Kita menyebut proses ini adalah subscribing.

Perhatikan bahwa kita selalu menambahkan instans dari delegate terhadap event. Pada contoh diatas kita membuat object delegate dengan ref new yang merujuk pada method OnPropertyChangedHandler pada kelas BlankPage.

(15)

Dengan cara ini kita mendapatkan token dari hasil registrasi tersebut. Token inilah yang dapat kita gunakan untuk melakukan unsubscribe (proses menghapus delegate yang sudah di register sebelumnya) terhadap delegate tersebut. Caranya adalah sebagai berikut

Anda dapat memilih salah satu dari kedua cara diatas untuk melakukan unsubscribe.

Event merupakan fitur yang sangat mempermudah kita untuk melakukan observer pattern. Tetapi jangan sampai salah menggunakannya karena juga akan dapat menyebabkan memory leak. Hal ini dapat terjadi jika lupa melakukan unsubscribe terhadap object yang tidak anda rujuk lagi.

Exception

Pada dunia pemrograman dengan COM kita menggunakan HRESULT untuk melihat apakah terjadi kegagalan operasi terhadap fungsi atau tidak. Hal ini menyebabkan code kita dapat terlihat seperti berikut. Sehingga yang terjadi adalah pengecekan HRESULT untuk setiap operasi yang kita eksekusi. Perhatikan code berikut

Dengan WinRT kita tidak lagi melakukan hal tersebut, karena kita sudah memiliki kelas dan semua fitur dari object oritend lainnya, kita dapat membuat Exception. Dengan demikian kita dapat melakukan hal diatas dengan lebih bersih. Jika terjadi kegagalan operasi maka kita akan melemparkan (throw)

(16)

Cara untuk melemparkan exception adalah dengan menggunakan keyword throw dan melewatkan instans dari object yang dibuat dengan ref new.

Berikut ini adalah relasi antara HRESULT dan tipe Exception yang terdapat pada WinRT.

Jika ada HRESULT yang belum memiliki tipe exception dan anda ingin melemparkan HRESULT tersebut. Mungkin anda ingin melakukannya untuk kompatibilitas dengan code COM yang telah anda buat sebelumnya, anda dapat menggunakan COMException sebagai berikut.

Anda menangkap exception tersebut dengan menggunakan try catch sebagai berikut. Anda juga dapat mengambil nilai HResult dari exception tersebut.

(17)

Salah satu hal yang perlu diperhatikan pada penanganan exception ini adalah bahwa induk dari segala exception yang ada pada WinRT adalah Platform::Exception. Sehingga jika anda ingin menangkap semua tipe exception yang dilemparkan dari method yang dipanggil kita menggunakan cara berikut ini

Generic

Mungkin anda bertanya-tanya mengapa kita membutuhkan tipe generic lagi, bukankah kita sudah memiliki template ? Apakah kita tidak lagi dapat menggunakan template ?

Hal yang pertama kali perlu kita ketahui adalah generic berbeda dengan template. Kita tetap saja dapat menggunakan c++ template. Generic dibutuhkan pada WinRT untuk membuat tipe generic yang dapat dikonsumsi oleh bahasa lain seperti c#, vb dan javascript. c++ template tidak akan dikenali jika keluar dari ABI.

Saya sudah membahas mengenai pentingnya programming to interface. Kita mungkin saja ingin membuat API yang dapat diakses oleh bahasa lain dengan mengembalikan interface yang generic sehingga kode client yang menggunakan API tersebut tidak terikat pada detail dari implementasinya. Berikut contoh dari generic interface

(18)

Jika anda melihat tanda garis bawah merah pada kode anda (yang biasanya ditujukan untuk

menandakan bahwa ada error ) maka anda dapat melakukan build untuk memastikan bahwa semua bisa di kompilasi. Kadang kadang error yang ditunjukkan tidak benar sehingga pastikan selalu dengan

melakukan kompilasi. Untuk versi beta ini masih banyak kesalahan untuk hal tersebut, sehingga anda harap maklum.

Generic interface ini dimengerti oleh WinRT metadata. Sehingga dapat digunakan dari bahasa lain. Kita tentu saja memerlukan kelas yang mengimplementasikan interrface tersebut. berikut cara untuk melakukannya.

Dengan adanya interface kita dapat menyembunyikan detail implemntasi dari kelas konkrit yang kita miliki. Aplikasi kita menjadi loose couple sehingga jika dikemudian hari terjadi perubahan maka kita dapat menggati kelas tersebut dengan kelas lain tanpa mempengaruhi kode program yang

menggunakan interface tersebut. Template Runtime Class

Generic dapat dimengerti oleh bahasa lain dan metadata, tetapi kita tetap saja membutuhkan template. Karena template memiliki fitur yang tidak dimiliki oleh generic. Kelebihan dari template terletak pada fleksibilitas, spesialisasi, compile time, kompresi. Hanya saja template tidak dikenali di luar c++ oleh bahasa lain. Tetapi kita tetap dapat menggunakannya dengan generic untuk memperoleh kombinasi yang sangat baik. Kita dapat memiliki template untuk class dengan sebagai berikut.

(19)

Kita menyembunyikan implemntasi dari template tersebut dari luar kode c++, sehingga c#, vb dan javascript tidak perlu mengetahui mengenai template tersebut.

Partial Runtime class

Dengan kelas parsial kita dapat memisahkan implementasi dari satu kelas ke beberapa file. Hal ini ditujukan untuk memisahkan code yang digenerate oleh tools dengan code yang kita tulis sendiri. Karena jika kita mengenerate ulang dengan bantuan tools dan kita melakukan perubahan pada file hasil generate tersebut, perubahan kita akan dihapus.

Visual studio sangat bergantung pada fitur ini untuk membuat XAML dan code behind bekerja dengan baik utk c++. Anda dapat melihatnya sendiri pada solution. Caranya adalah aktifkan Show All Files sehingga anda dapat melihat semua code yang digenerate.

Anda akan melihat beberapa file yang digenerate memiliki nama yang sama dengan kelas dimana kita sebelumhya bekerja. BlankPage.h memiliki pasangan BlankPage.g.h. Jika anda melihat isi dari

(20)

Pasangannya adalah BlankPage.h yang telah kita sering gunakan sebelumnya.

Pada saat compile time maka kedua kelas tersebut akan digabungkan menjadi satu seolah-olah semua isi kode yang ada di kelas partial BlankPage.g.h tersebut ada di kelas BlankPage.h.

Library

WinRT memiliki kelas Collection sendiri, hal ini tentu saja ditunjukan untuk kepentingan ABI (Abstract Binary Interface). Kita tetap saja dapat menggunakan collection dari STL yang sudah sering kita gunakan dan kedua tipe tersebut dapat saling bekerja sama dengan mudah.

Vector

Pada WinRT collection kita memiliki Vector dan ObserverableVector. Anda tentu sudah mengetahui bahwa pada STL kita memiliki std::vector. Vector terletak pada namespace Platform::Collection. Kita dapat menggunakannya dengan cara berikut. Pertama jangan lupa untuk using namespace tersebut

(21)

Jika anda ingin melakukan iterasi terhadap Vector tersebut anda dapat menggunakan IVectorView yang dilakukan dengan cara berikut.

IVectorView merupakan iterator yang hanya dapat dibaca saja isinya tanpa merubah (read only). Tujuannya digunakan untuk melakukan navigasi terhadap elemen dari vector tersebut.

Vector juga memiliki mekanisme untuk memberitahukan apabila terjadi perubahan pada vector

tersebut, penambahan elemen dsb. Hal itu dilakukan dengan menggunakan event dan delegate sebagai berikut.

Map

Untuk tipe dictionary dengan key dan value, kita memiliki Map yang memiliki padanan dengan std::map pada c++ standard. Sama dengan Vector terletak pada Platform::Collection. Berikut sekilas cara

penggunaanya.

(22)

Kita dapat menggunakan kelas kelas collection WinRT yang dijelaskan pada bagian sebelum dengan STL. Kita sudah tahu bahwa agar algoritma yang ada pada STL dapat bekerja kita harus memiliki method begin() dan end() pada kelas yang akan kita iterasi. Kelas String dan Collection yang ada pada WinRT telah mengimplementasikan kedua method tersebut sehingga dapat bekerja dengan baik dengn algoritma STL. Berikut kita lihat cara penggunaanya.

Jika anda lakukan analisa terhadap kode tersebut maka kita tidak melihat banyak perbedaan dengan apa yang kita lakukan pada kode c++ standard sebelumnya. begin() dan end() sudah di implementasikan oleh setiap WinRT collection pada collection.h. Anda dapat membuktikannya dengn membuka file

collection.h. Anda dapat menemukannya pada solution explorer pada bagian external dependency.

Atau anda dapat langsung melakukan navigasi dengan memanfaatkan bantuan search visual studio dengan cara klik kanan pada code begin() atau end() dan pilih go to definition (F12).

(23)

Anda dapat memperhatikan definisi tersebut seperti berikut.

seperti yang sudah kita pelajari pada bagian sebelumnya kita dapat menggunakan tipe c++ standard di dalam boundary (ABI), tetapi jika kita telah melewati batas tersebut kita harus menggunakan tipe WinRT. Oleh karena itu kita membutuhkan cara untuk konversi dari WinRT ke c++ standard dan sebaliknya. Fungsi konversi tersebut sudah disediakan dan tinggal kita gunakan saja.

(24)

Dari std::wstring ke Platform::String kita menggunakan Constructor String seperti berikut ini.

Dari std::vector ke Platform::Collections::Vector kita melakukan dengan bantuan Constructor seperti yang kita lakukan pada String sebelumnya seperti berikut

Untuk mengubah Platform::Collections::Vector menjadi std::vector maka kita menggunakan fungsi yang ada pada collection.h yaitu to_vector() seperti berikut ini

Anda dapat melihat definisi dari to_vector dengan menekan F12 pada fungsi tersebut. definisi tersebut terletak di collection.h

Referensi

Dokumen terkait

➢ Meminta penjelasan terkait dengan makalah calon tidak menyentuh perspektif HAM, bahwa Komnas HAM dibentuk pemerintah karena terpaksa, musuh terbesar kita adalah

Lukisan berjudul Women III adalah merupakan hasil karya yang dibuat oleh seniman yang menganut aliran lukisan abstrak ekspresionis willem de Kooning dan merupakan salah satu

Konsep rumah tangga pertanian adalah rumah tangga yang salah satu atau lebih anggota rumah tangganya melakukan dan bertanggungjawab dalam kegiatan pembudidayaan,

Seminar yang dilakukan di kantor Pusat Penelitian dan Pengembangan Geologi Kelautan (P3GL) 6irebon, dilakukan dalam a6ara peringatan hari %usantara yang ke & pada tanggal

Menentukan kondisi operasi yang optimal (daya microwave , lama waktu ekstraksi, dan rasio antara bahan baku yang akan diekstrak dengan pelarut yang digunakan) dari

Peluang ini dilirik penulis untuk membuat aplikasi mobilebebas biaya sehingga pengguna dapat ber-chatting ria secara mobile dan interaktif, real-time dimana saja, karena

Teo berasal dari kata Teos yang berarti tuhan atau ajaran agama, saintisme berasal dari kata sains yang berarti ilmu pengetahuan, dan saintisme adalah aliran atau paham

Inti dari model pembelajaran Student Facilitator and Explaining merupakan model pembelajaran dimana peserta didik dibagi kedalam beberapa kelompok, dan tiap-tiap