CB KEWARGANEGARAAN: KEGIATAN – KEGIATAN PEDULI TERHADAP LINGKUNGAN versi Scan Laporan
Link video: https://drive.google.com/open?id=0B6C6vMtshyDnUmtQLVZKaTVzZG8
Link video: https://drive.google.com/open?id=0B6C6vMtshyDnUmtQLVZKaTVzZG8
Link video: https://drive.google.com/open?id=0B6C6vMtshyDnUmtQLVZKaTVzZG8
NIM | Nama | Jabatan (ketua, sekertaris, anggota) |
2001565346 | Edbert | Ketua |
2001599076 | Wendy Yanto | Sekretaris |
2001557703 | Gabriellyan Catheline Sanger | Anggota |
2001543175 | Harry Darmawan | Anggota |
2001541586 | Juanietto Forry Kusuma | Anggota |
2001546416 | Martandy | Anggota |
2001564040 | Tommy Phen | Anggota |
Kelas | LI01 |
Judul Project | : | Menanam Pohon Untuk Lingkungan yang Lebih Hijau | |
Lokasi Project | : | Hutan Kota Srengseng, Jalan Haji Kelik RT.8/RW.6, Srengseng, Kembangan, RT.8/RW.6, Srengseng, Jakarta Barat, Kota Jakarta Barat, DKI Jakarta 11630, Indonesia | |
Kelompok target kegiatan | : | Lingkungan sekitar hutan kota srengseng | |
Nama Anggota Kelompok | |||
1. | : | Edbert (2001565346) | |
2. | : | Gabriellyan Catheline Sanger (2001557703) | |
3. | : | Harry Darmawan (2001543175) | |
4.
5. 6. 7. |
:
: : : |
Juanietto Forry Kusuma (2001541586)
Martandy (2001546416) Tommy Phen (2001564040) Wendy Yanto (2001599076) |
|
Mata Kuliah | : | Character Building Kewarganegaraan | |
Kelas | : | LI01 | |
Dosen | : | Hari Sriyanto (D2715) |
BAB I
PENDAHULUAN
Pada era sekarang ini, teknologi dan pola kehidupan manusia sudah semakin berkembang ditambah dengan populasi manusia yang semakin meningkat pun menambah kemungkinan kehidupan bermasyarakat untuk berkembang. Namun dibalik semua hal itu, sumber utama untuk kelangsungan kehidupan kita yaitu oksigen pun semakin berkurang dikarenakan oleh perkembangan teknologi dan pola kehidupan yang mulai melupakan pentingnya alam bagi kehidupan sehari-hari. Hal ini ditandai dengan tampaknya masyarakat mulai melupakan budaya untuk menanam pohon dan untuk kepentingan pihak tertentu malah menghilangkan sumber oksigen itu untuk mendapatkan keuntungan tersendiri. Hal ini merupakan sesuatu yang sudah dimengerti namun tetap saja dihiraukan oleh masyarakat. Oleh Karena itu, kami pun memanfaatkan kegiatan social CB ini untuk melakukan penanaman pohon di Hutan Kota Srengseng, Jakarta Barat untuk menambah pohon-pohon yang pada kedepannya akan menghasilkan oksigen yang dapat dipakai bersama.
Problematika yang selalu ada di Indonesia adalah kurangnya kesadaran masyarakat akan pentingnya peran pohon dalam kehidupan sehari-hari serta tindakan para oknum yang tidak bertanggung jawab baik dengan menebang secara liar maupun membakar lahan yang dapat dimanfaatkan sebagai tempat penanaman pohon dan hasil dari pembakaran itu pun menimbulkan asap yang semakin mengurangi oksigen yang ada, sehingga mengurangi jumlah pohon-pohon yang ada. Maka dari itu dilakukanlah kegiatan menanam pohon ini untuk mencapai kehidupan bermasyarakat yang layak.
Dalam rencana kegiatan, diputuskan untuk pertama sekali melakukan survey di Hutan Kota Srengseng dan membeli bibit pohon untuk penanaman di lokasi tersebut. Rencana kegiatan dapat dipecah menjadi beberapa pertemuan dimana pada:
BAB II
Metode Kegiatan
Secara garis besar rencana kegiatan ini dapat dibagi menjadi beberapa poin:
Pertama, kegiatan dimulai dengan mencari lokasi penanaman pohon yang dimana didapati pada Hutan Kota Srengseng. Komunikasi antar pihak berlangsung melalui telepon dan menyepakati jadwal yang ada untuk mengunjungi Hutan Kota untuk melakukan survey lokasi.
Kemudian membeli bibit pohon di Hutan Kota Srengseng yaitu bibit pohon Keben sebanyak 5 buah, dilanjutkan dengan mencari lokasi yang tersedia sebagai tempat penanaman bibit, dan peralatan yang diperlukan untuk menanam telah disediakan oleh petugasnya.
Proses penanaman pohon ini dilakukan dengan menggali tanah secukupnya, kemudian ditanam bibit pohon ke dalam galian tanah dan ditutupi kembali, setelah itu diberikan 2 batang bambu untuk memberikan fondasi untuk bibit pohon tumbuh.
Selanjutnya dilakukan perawatan bibit pohon dengan melakukan penyiraman air ke setiap bibit pohon yang sudah ditanam secukupnya. Untuk menambah penyuburan pohon, maka disepakati untuk membeli pupuk kompos dari tempatnya dan menaruhnya di sekitar bibit itu.
BAB III
Konsep
Kita sebagai warga negara Indonesia sudah selayaknya merawat dan melindungi tanah air kita. Kami melakukan kegiatan menanam pohon atas dasar konteks kewarganegaraan sebagaimana kita harus saling menghargai dan menjaga tanah air kita dan juga untuk mencegah pemanasan global. Untuk menjaga kelestarian lingkungan kota, kami melakukan kegiatan dengan cara menanam pohon dengan memanfaatkan hutan kota sebagai lokasi penanaman yang baik dan tepat.
Melihat kondisi seperti pemanasan global yang tiada hentinya, sirkulasi air yang tidak baik diakibatkan penebangan hutan untuk membuka lahan baru sebagai tempat pemukiman tanpa melakukan reboisasi, serta peningkatan jumlah polusi udara yang diakibatkan oleh limbah udara dari pabrik dan kendaraan, maka kami ingin melaksanakan tugas Character Building dengan membangun sikap cinta terhadap tanah air kita dengan cara melestarikan lingkungan yang berada disekitar kita.
Kami mengambil kegiatan ini karena sesuai dengan nilai-nilai yang terkandung pada konteks kewarganegaraan. Pada pasal 27 ayat 3 Undang – Undang Dasar 1945 berbunyi “Setiap warga negara berhak dan wajib ikut serta dalam upaya pembelaan negara”, hal tersebut menunjukkan kita sebagai warga negara memiliki kewajiban dalam membela negara. Pembelaan negara tidak hanya berupa melakukan peperangan, tetapi juga bisa dengan ikut serta dalam melestarikan alam Indonesia, salah satunya dengan melakukan reboisasi atau penghijauan kembali hutan – hutan yang gundul akibat penebangan hutan juga untuk menjernihkan udara dari polusi udara yang berlebihan terutama di kota – kota besar seperti Jakarta.
Dengan pelaksanaan kegiatan menanam pohon ini, kami berharap dapat memberikan dampak yang besar kepada lingkungan agar lebih baik serta menjadikan kota Jakarta menjadi kota yang bebas polusi udara dan menyejukkan udara dari pemanasan global.
BAB IV
Pelaksanaan Kegiatan
Kegiatan dibagi menjadi 5 pertemuan. Lokasi kegiatan berada di Hutan Kota Srengseng.
Kegiatan pertemuan pertama kami melakukan survey dilokasi Hutan Kota Srengseng. Kami memilih tanaman yang nantinya akan kami tanam disana. Tanaman yang kami pilih adalah bibit pohon keben. Selanjutnya kami memilih lahan yang nantinya dijadikan sebagai wadah penanaman bibit pohon kami.
Lokasi kegiatan: Hutan Kota Srengseng
Waktu kegiatan: Minggu, 12 Maret 2017
Pihak yang dilibatkan: Bapak Rojak (Pengurus Hutan Kota Srengseng).
Pada pertemuan kedua, kami melakukan kegiatan penanaman bibit pohon keben. Kami menanam 5 buah bibit pohon keben di sekitar lokasi yang sudah ditentukan pada pertemuan pertama. Kami memulai penanaman dengan peletakan bibit pohon keben pada tanah yang sudah digali, kemudian mengubur bagian akar sampai batang bawah bibit dengan tanah galian. Setelah itu, kami mengikat dan menyanggah bibit pohon dengan bamboo agar dapat tumbuh dengan tegak dan kokoh.
Lokasi kegiatan: Hutan Kota Srengseng
Waktu kegiatan: Rabu, 22 Maret 2017
Pihak yang dilibatkan: Bapak Rojak (Pengurus Hutan Kota Srengseng).
Pada pertemuan ketiga, kami melakukan perawatan pada bibit pohon kami dengan cara pemyiraman dengan air supaya bibit pohon dapat tumbuh dengan baik. Pertumbuhan pada bibit pohon kami mulai terlihat dengan bertambah tingginya bibit pohon kami sejak penanaman.
Lokasi kegiatan: Hutan Kota Srengseng
Waktu kegiatan: Sabtu, 15 April 2017
Pihak yang dilibatkan: Bapak Rojak (Pengurus Hutan Kota Srengseng).
Pada pertemuan keempat, kami memberikan pupuk kompos pada bibit pohon kami. Pemberian pupuk kompos ini bertujuan agar tanaman dapat tumbuh subur. Pertumbuhan pada bibit pohon kami semakin baik dengan mulai melebarnya daun pada bibit pohon keben kami.
Lokasi kegiatan: Hutan Kota Srengseng
Waktu kegiatan: Senin, 17 April 2017
Pihak yang dilibatkan: Bapak Rojak (Pengurus Hutan Kota Srengseng).
Pada pertemuan kelima, kami melakukan perawatan dengan penyiraman air pada bibit pohon. Pertumbuhan pohon kami sudah baik dengan bertambah tinggi batang tanaman dan terlihat semakin kokoh dengan batang yang semakin menebal.
Lokasi kegiatan: Hutan Kota Srengseng
Waktu kegiatan: Kamis, 11 Mei 2017
Pihak yang dilibatkan: Bapak Rojak (Pengurus Hutan Kota Srengseng).
BAB V
Penutup
Banyak hal yang bisa kita petik dari kegiatan penanaman pohon ini, alasan kami memilih untuk menanam pohon di Hutan Kota Srengseng adalah karena Indonesia merupakan penghasil emisi gas rumah kaca terbesar kelima di dunia. Hal tersebut disebabkan oleh konversi hutan dan lahan gambut yang kaya akan karbon menjadi lahan-lahan lain di Indonesia. Perubahan pada lahan-lahan hijau tersebut memiliki konsekuensi dalam bidang ekonomi dan sosial, karena hutan Indonesia adalah rumah bagi ribuan spesies tanaman dan hewan dan juga 50-60 juta penduduk Indonesia bergantung pada hutan untuk mata pencaharian langsung mereka. Diharapkan dengan penanaman pohon yang kelompok kami lakukan dapat memperbaiki Indonesia dalam bidang ekonomi, sosial, dan bahkan ribuan spesies tanaman dan hewan yang telah kehilangan habitat mereka.
Dengan kegiatan penanaman pohon ini, kami sebagai penanam juga mendapatkan sebuah pengalaman yang berharga dan sebagai penanam kami merasa bahwa kita harus lebih lagi mencintai alam kita Indonesia. Meskipun apa yang kami lakukan bukanlah hal yang signifikan, tetapi dalam beberapa minggu ini, kami telah menyadari betapa pentingnya lahan hijau bagi kehidupan kami.
Berikut ini adalah kesimpulan yang didapatkan dari tiap anggota kelompok ini:
Tidak mudah untuk melaksanakan sebuah kegiatan, walaupun dalam lingkup yang kecil, perbedaan jadwal masing-masing anggota dapat mengganggu jalannya kegiatan, namun hal tersebut tidak mengganggu kegiatan secara signifikan.
Dengan adanya kegiatan ini juga, saya secara pribadi lebih mengerti mengenai jenis-jenis pohon dan cara merawatnya.
Oksigen merupakan sumber utama untuk kehidupan kita dan hanya dapat dihasilkan oleh tanaman atau pohon. Ini menunjukkan betapa pentingnya peran pohon dalam kehidupan sehari-hari. Jadi kami memilih penanaman pohon untuk kegiatan CB kewarganegaraan sehingga dapat mengurangi permasalahan yang ada dan menambah oksigen untuk kehidupan sehari-hari. Jadi kami merasa dengan dilakukanya kegiatan ini dapat bermanfaat untuk masyarakat dan dapat menjadi contoh untuk masyarakat sehingga menyadari pentingnya peran pohon.
Kegiatan menanam pohon ini telah menunjukkan nilai kepedulian terhadap lingkungan. Hal ini sangat mendorong pada pembentukan karakter rasa kepedulian dan cinta terhadap tanah air ibu pertiwi kita. Semoga kegiatan ini semakin banyak dilakukan oleh masyarakat sebagai wujud kepedulian warga negara terhadap lingkungan di Indonesia.
Manusia terhadap alam adalah dua hal yang tidak bisa dipisahkan. Namun kita sebagai penghuni alam ini kurang peduli dengan alam yang ternyata banyak memberi penghidupan kepada semua penghuninya. Dengan kegiatan penanaman pohon ini menjadi salah satu media untuk saya dan kelompok saya untuk membalas kebaikan yang telah alam berikan kepada saya dan kelompok saya, serta secara tidak langsung ikut serta dalam pembangunan negara Indonesia.
Kegiatan penanaman pohon ini sangat bermanfaat untuk membangun karakter pada diri kita dan sesama terutama rasa cinta terhadap tanah air kita Indonesia.
Kegiatan ini sangat bermanfaat bagi tanah air karena melestarikan lingkungan tanah air dan memberi banyak manfaat bagi warga dan makhluk hidup lainnya.
Kesimpulan dari kegiatan ini yaitu kita dapat belajar proses-proses penanaman pohon dari menanam sampai proses perawatan, selain itu kita juga dapat membantu lingkungan sekitar dengan melakukan penanaman pohon, Kegiatan ini juga dapat membuat masyarakat yang berada pada saat proses penanaman menjadi tertarik untuk melakukan penanaman pohon.
Dalam kegiatan ini, ada beberapa hal yang perlu dikembangkan lagi, baik bagi kami sebagai pelaksana kegiatan, perwakilan Hutan Kota Srengseng yang menjadi fasilitator kegiatan, serta bagi dosen kami sebagai pembimbing dalam kegiatan ini. Adapun saran-saran tersebut antara lain:
Adapun berikut ini saran-saran yang masing-masing anggota kelompok ini bisa sampaikan:
Semoga untuk kedepannya jika bekerja dalam satu kelompok lagi, semuanya bisa tetap bekerja sama dengan baik.
Saran untuk kegiatan ini dapat ditingkatkan lagi sehingga dapat menjangkau seluruh masyarakat Indonesia tidak hanya dari Universitas Bina Nusantara saja, sehingga seluruh masyarakat dapat berpastisipasi sebagai satu kesatuan dalam menanam pohon untuk kehidupan bermasyarakat yg lebih baik.
Sebaiknya kegiatan ini dijadikan sebagai program rutinitas gotong royong RT dan RW kepada masyarakat sekitar.
Harapan saya adalah agar kedepannya kegiatan ini tidak hanya dilakukan sebatas untuk tugas kemanusian saja tetapi menjadi suatu gaya hidup bagi diri kami masing-masing agar dapat menjadi teladan dan menginspirasi banyak orang untuk lebih peduli dan mencintai alam negeri kami Indonesia.
Sebaiknya kegiatan ini tetap diadakan demi pelestarian lingkungan mengingat pentingnya kelestarian hidup bagi kita sebagai manusia maupun makhluk hidup lainnya.
Kegiatan ini sangatlah bermanfaat, saran untuk kedepannya agar dapat lebih baik dan diperbanyak kegiatan seperti ini agar lingkungan dapat lebih terjaga kelestariannya.
Saran saya sih untuk kedepannya kalau ada binusian yang ingin melakukan kegiatan penanaman pohon lagi, semoga bisa melakukan lebih dari 5 kali pertemuan karena terasa terlalu sedikit.
Dari 17 negara yang disurvei di seluruh dunia menurut YouGov (https://my.yougov.com/en-my/news/2016/03/01/global-survey-malaysia-and-indonesia-among-least-c/), Indonesia termasuk yang paling tidak peduli dengan perubahan iklim – namun berada di antara yang paling peduli dengan stabilitas ekonomi. Padahal perubahan iklim sangatlah berpengaruh terhadap mata pencaharian kebanyakan penduduk Indonesia. Dengan menyadari pentingnya hutan tropis bagi masyarakat domestik dan internasional, kami melakukan kegiatan penanaman pohon ini dengan harapan kedepannya semoga dengan adanya kegiatan seperti ini dapat menginspirasi banyak orang untuk lebih mencintai alam Indonesia, minimal dengan langkah kecil seperti menanam pohon skala kecil, atau dalam gerakan skala besar. Niscaya, Indonesia akan menjadi lebih maju tidak hanya dalam bidang sosial maupun ekonomi.
Lampiran 1: Notulensi Kegiatan Diskusi Kelompok
Anggota yang tidak hadir:
Lampiran 2: Survey Lokasi
Anggota yang tidak hadir:
Dalam survei ini, kami telah menentukan hutan kota srengseng sebagai tempat tujuan kegiatan kita karena lokasinya yang dekat dengan Universitas Bina Nusantara. Kami juga telah meminta izin kepada pihak pengelola Hutan Kota Srengseng untuk melakukan kegiatan penanaman pohon. Mengenai hal ini, kami juga telah menentukan bibit pohon keben setelah direkomendasi dengan pihak pengelola hutan kota srengseng dan telah sepakat dengan pihak pengelola hutan bahwa peralatan penanaman pohon akan disediakan(dipinjamkan) oleh pihak pengelola hutan
Lampiran 3: Kegiatan
Anggota yang tidak hadir:
Anggota yang tidak hadir:
Lampiran 4: Pembagian Tugas Pembuatan Laporan Akhir
Link Video:
Kevin Winarko(2001554260)
saberkevin.blog.binusian.org
Tommy Phen (2001564040)
tommyphen27.blog.binusian.org
Piterson Satio(2001557230)
piterson.blog.binusian.org
Wendy Yanto (2001599076)
wendy98.blog.binusian.org
Edbert (2001565346)
ed1001bert.blog.binusian.org
Robert W. Sebesta – Concept of Programming Languages (Tenth Edition)
http://www2.southeastern.edu/Academics/Faculty/galkadi/401/notes/chapter1.doc
http://cseweb.ucsd.edu/classes/sp05/cse130/lecture_notes/types_student.txt
http://www-h.eng.cam.ac.uk/help/languages/C++/c++_tutorial/assignment.html
https://courses.cs.vt.edu/~cs3304/Spring02/lectures/lect08.pdf
https://www.cs.upc.edu/~jordicf/Teaching/programming/pdf/IP05_Functions.pdf
https://www.tutorialspoint.com/cplusplus/cpp_exceptions_handling.htm
https://www.tutorialspoint.com/cplusplus/cpp_object_oriented.htm
https://www.tutorialspoint.com/cplusplus/cpp_data_abstraction.htm
https://www.tutorialspoint.com/cplusplus/cpp_data_encapsulation.htm
https://meetingcpp.com/tl_files/mcpp/2015/talks/Nicola%20Gigante%20-%20functionalcpp.handout%20-%20Meeting%20C++%202015.pdf
w3schools.in/cplusplus/data-types/
What is logic programming? – Programming based on the notion of logical deduction in symbolic logic. – Implementation typically based on mechanisms for automatic theorem proving
History and Goals of Logic Programming (cont)
Introduction to Prolog
Prolog (PROgramming in LOGic) is first and most important logic programming language. Developed in 1972 by Alain Colmerauer in Marseilles.Relational rather than functional programming language Often best to start out as thinking of Prolog in terms of language for working with a data base.
Pure Prolog
There are three types of statements:
We should think of language as non-deterministic (or non-procedural). Looks for all answers satisfying query
Example:Facts
father(ralph,john). father(ralph,mary). father(bill,ralph).
mother(sue,john). mother(sue,mary). mother(joan,ralph).
male(john). male(ralph). male(bill).
female(mary). female(sue).
Example: Rules
is_mother(M) :- mother(M,Y).
parent(M,X) :- mother(M,X).
parent(F,X) :- father(F,X).
parents(M,F,X) :- mother(M,X), father(F,X).
sister(X,S) :- female(S), parents(M,F,X), parents(M,F,S), S\=X.
ancester(X,Y) :- parent(X,Y).
ancester(X,Y) :- parent(X,Z),ancester(Z,Y).
Selection Sort
sel_sort([],[]).
sel_sort(L,[Small|R]) :-
smallest(L,Small) ,
delete(Small,L,Rest) ,
sel_sort(Rest,R) .
/*smallest(List, Small) results in Small being the smallest element in List.*/
smallest([Small],Small) .
smallest([H|T],Small) :-
smallest(T,Small) ,
Small=<H.
smallest([H|T],H).
/* delete(Elt,List,Result) has Result as List after deleting Elt. */
delete(Elt,[],[]) .
delete(Elt,[Elt|T],T) .
delete(Elt,[H|T],[H|NuTail]) :-
delete(Elt,T,NuTail)
Insertion Sort
ins_sort([],[]) .
ins_sort([H|T],Sorted) :-
ins_sort(T,Rest),
insert(H,Rest,Sorted) .
/* insert(Elt,List,Result) – if List is sorted, Result is obtained by putting Elt where it fits in order in List. */
insert(Elt,[],[Elt]) .
insert(Elt,[H|T],[Elt,H|T]) :-
(Elt=<H)
insert(Elt,[H|T],[H|Sorted]) :-
insert(Elt,T,Sorted) .
QuickSort
/* sep(List,Key,Less,More) separates the List into the set of elements less than or equal to Key (in Less) and those greater than or equal to Key (in More) */
sep([],Key,[],[]) .
sep([H|T],Key,Less,[H|More]) :-
(H>Key) ,
sep(T,Key,Less,More) .
sep([H|T],Key,[H|Less],More) :-
(H=<Key) ,
sep(T,Key,Less,More) .
quick_sort([],[]) .
quick_sort([H|T],Sorted) :-
sep(T,H,Less,More) ,
quick_sort(Less,L_sorted) ,
quick_sort(More,M_sorted) ,
concat(L_sorted,[H|M_sorted],Sorted) .
/* concat(First, Second, List) results in List = concatenation of First and Second. */
concat([],L,L) .
concat([H|T],L,[H|C]) :- concat(T,L,C) .
Permutations
Can take advantage of reversibility since computing with relations rather than functions.
append([],L,L) .
append([H|T],L,[H|R]) :- append(T,L,R) .
permute([],[]) .
permute(L,[H|T]) :-
append(V,[H|U],L) ,
/* V,U stand for the part of L before and after H */
append(V,U,W) ,
permute(W,T) .
Logical vs Procedural Reading of Programs
father(ralph,john). father(ralph,mary). father(bill,ralph).
mother(sue,john). mother(sue,mary). mother(joan,ralph).
parent(M,X) :- mother(M,X).
parent(F,X) :- father(F,X).
ancester(X,Y) :- parent(X,Y).
ancester(X,Y) :- parent(X,Z),ancester(Z,Y).
?-ancester(joan,X).
– First succeeds with X = ralph
– Second X= john
– Third X = mary
Operators in Prolog
Operators in Prolog Usually used as prefix, can force to be in infix or postfix and give precedence as well.
Example: arithmetic operators: 2+3*5 abbreviates +(2,*(3,5)) • Operations are not evaluated .Better to think of operations as forming tags on values
– Forming records
– Don’t really compute anything
– Typically uninterpreted
Relations =, \=, , == (note order of composite relations) are evaluated. digit(N):- N>=0,N<10.
Example of Using Operations
– Tree is either nil or is of form maketree(tree1,X,tree2).
– Programs to manipulate trees use pattern matching like in ML
– If actually wish to calculate, must use is.
– Ex. area(L,W,A) :- A is L*W.
– Can only compute A from L,W — not reversible
Graphs
Look at this program to find paths in graph
edge(a,b).
edge(a,f).
edge(b,c).
edge(c,a).
edge(d,e).
edge(e,a).
edge(e,c).
dumb_path(Start,Finish) :- edge(Start,Finish).
dumb_path(Start,Finish) :- edge(Start,Next),dumb_path(Next,Finish).
And then what will happens if we type:
?- dumb_path(a,c). ?- dumb_path(a,e).
The Problem will continues to go through same vertex multiple times.But if we use a more smarter program , it will keeps track of vertices which are visited.
path(Start,Finish) :- smart_path(Start,Finish,[]).
smart_path(Current,Target,Visited) :- edge(Current,Target).
smart_path(Current,Target,Visited) :-
edge(Current,Next),non_member(Next,Visited),
smart_path(Next,Target,[Next|Visited]).
non_member(Elt,[]).
non_member(Elt,[Hd | Tl]) :- Elt \== Hd, non_member(Elt,Tl).
Adjacency Lists
Note that database representation of graph is not only possibility. We can use adjacency list representation. Write graph as list of vertices and corresponding edges:
– Each vertex included with list of all edges going from it.
– E.g. node a represented by v(a,[b,f])
– Whole graph given by [v(a,[b,f]), v(b,[c]), v(c,[a]), v(d,[e]),v(e,[a,c])].
The advantage of adjacency lists is that it can add vertices and edges during a computation.
Write:
– vertex(Graph,Vertex) which tells if Vertex is in Graph:
vertex([v(Vert,Edge) | Rest],Vert).
vertex([_ | Rest],Vert) :- vertex(Rest,Vert).
– edge(Graph,X,Y) true if there is an edge from X to Y.
edge(Graph,X,Y) :- member(v(X,Edges),Graph),
member(Y,Edges).
Edge(Graph,X,Y) :- member(v(Y,Edges),Graph),
member(X,Edges).
And the rest of program for paths is as before.
Russian Farmer Puzzle
Variation of missionary and cannibals
Farmer taking goat and (giant) cabbage to market. Wolf following farmer. Come to river with no bridge, but only tiny boat big enough to hold farmer and one object. How can farmer get all three across river without goat eating cabbage or wolf eating goat?
Specify solution
– At any time during solution, describe current state by noting which side of river each of farmer, goat, cabbage and wolf are on (call them north/south).
– Can write down all states and all allowable transitions and then find path. (Like finding path in graph)
Representation
Really only 4 possible actions: Farmer crosses with one of goat, cabbage, and wolf, or farmer crosses alone. We write rules for each of it.Then,we describe states by terms — state(F,G,C,W) where each of F, G, C, W is one of north, south.We also need predicate “opposite” like : opposite(north,south). opposite(south,north).
Axiomatizing Actions
transition(state(F0,F0,C,W),state(F1,F1,C,W)) :- opposite(F0,F1).
transition(state(F0,G,F0,W),state(F1,G,F1,W)) :-
opposite(F0,F1), opposite(G,W).
transition(state(F0,G,C,F0),state(F1,G,C,F1)) :-
opposite(F0,F1), opposite(G,C).
transition(state(F0,G,C,C),state(F1,G,C,C)) :-
opposite(F0,F1),opposite(G,C).
Cut
Cut — curtails backtracking. pred(. . .):-cond1, . . . , condk, !, condk+1, . . . , condn. Cut ! is always satisfied — freezes all previous choices .If we get to point where no more solutions to condk+1,. . ., condn then all of pred(. . .) fails and no other clause or rule for pred will hold. Backtracks until ! satisfied and then never backtracks over it.
Uses of Cut :
Cut Examples
sum_to(1,1).
sum_to(N,Sum) :- Pred is N-1, sum_to(Pred,Partial_sum),
Sum is Partial_sum + N.
Fail
The program might result in Fail If we can exclude some cases early on, Can use cut to terminate search. Possible_Pres(willy) :- !,fail. Possible_Pres(X) :- NativeBorn(X).Fail is predicate that is never satisfied.
Problems with Cut
Cut and Reversibility
. • Now only get one answer (when running either direction).
Formal Basis for Prolog
– The fact A(a,b,c) is just treated as an atomic statement which is asserted to be true.
– The rule A(X,Y) :- B(X,Y),C(X,Y). is understood as logical statement ∀X, Y.(B(X, Y ) ∧ C(X, Y ) → A(X, Y ))
Horn Clauses
Resolution Theorem Proving
Is there a proof of ∃X, Y.D(X, Y ) from statements in program? To answer this question we need Resolution Theorem Proving. Resolution theorem proving works by attempting to show that hypotheses and negation of conclusion (i.e. ∀X, Y. ∼ D(X, Y )) generate a contradiction. Contradiction is essentially found by finding values for X, Y such that D(X, Y ).
Prolog and Horn Clauses
. • Prolog does not implement resolution correctly.
Negation in Prolog
Negation is based on assumption of complete knowledge: if system cannot prove statement is true, then it must be false.In here there are three possible outcomes of proof: Succeeds, fails,and doesn’t terminate
Returns false only if it fails (finite failure).If attempt never terminates then don’t report it false!
Note that this is a non-monotonic rule of reasoning.
Built-in predicate not defined so that not(X) succeeds if an attempt to satisfy X fails.
not(X) fails if an attempt to satisfy X succeeds.
not(X) :- X,!,fail.
not(X).
Thus ?- not(father(shezad,kim)).
reports true.
However if add fact, father(shezad,kim), then will reverse answers.
In family program from above, since there is no fact corresponding to father(shezad,kim), system deduces that it is false.
Not Strangeness
childless(X) :- not(father(Y,X)),not(mother(Z,X)).
– If fred not mentioned childless(fred) will return yes
– But childless(Z) returns no.
old(X) :- not(young(X)).
young(X) :- not(old(X)).
get the opposite response, everything is young!
Not Cautions
. • Safest if only use not on predicates which have no free variables (i.e., make sure variables instantiated before calling it!).
Evaluation of Logic Programming and Prolog
– One of few examples of non-procedural languages. (well, sort of)
– Generalize by replacing unification by, e.g., solving systems of inequalities. Constraint logic programming.
The design of the imperative languages is based directly on the von Neumann architecture. The design of the functional languages is based on mathematical functions
Simple Functions
A mathematical function is a mapping of members of one set, called the domain set, to another set, called the range set. Function definitions are often written as a function name, followed by a list of parameters in parentheses, followed by the mapping expression. For example, cube(x) ≡ x * x * x, where x is a real number.
A lambda expression specifies the parameter(s) and the mapping of a function in the following form for the function cube(x) = x * x * x :
ë(x) x * x * x
Lambda expressions describe nameless functions. Lambda expressions are applied to parameter(s) by placing the parameter(s) after the expression. Application of the example lambda expression is denoted as in the following example: (ë (x)x * x * x)(2) which results in the value 8.
Functional Forms
A higher-order function, or functional form, is one that either takes one or more functions as parameters or yields a function as its result, or both. One common kind of functional form is function composition, which has two functional parameters and yields a function whose value is the first actual parameter function applied to the result of the second. Function composition is written as an expression, using ° as an operator, as in h ≡ f ° g
For example, if f (x) ≡ x + 2 and g (x) ≡ 3 * x then h is defined as h (x) ≡ f ( g ( x)), or h(x) ≡ (3 * x) + 2.
Apply-to-all is a functional form that takes a single function as a parameter and yields a list of values obtained by applying the given function to each element of a list of parameters. Apply-to-all is denoted by á.
For h(x) ≡ x * x, á(h, (2, 3, 4)) yields (4, 9, 16).
The following is the example of using lambda expression in C++:
auto f(std::vector) -> float;
auto g(std::string) -> std::vector;
auto h(std::istream&) -> std::string;
auto fgh = compose(f, g, h);
int x = fgh(std::cin); // x = f(g(h(std::cin)))
Functional Programming has a few core principles:
Reasons to program functionally in C++:
One of the main abstraction tools in Functional Programming is the concept of higher order functions. Functions that take other functions as arguments and return other functions. Functions in header <algorithm> are a good old example. The introduction of lambdas in C++11 allows to officialy say that this pattern is encouraged in C++.
Examples of lambda functions in C++:
// Sort by absolute value
class abs_cmp {
public:
bool operator()(int i, int j) const {
return std::abs(i) < std::abs(j);
}
};
std::sort(begin(v), end(v), abs_cmp{});
// Roughly equivalent to the following anonymous lambda expression
std::sort(begin(v), end(v), [](int i, int j){
return std::abs(i) < std::abs(j);
});
What’s great about C++ lambdas is that they do not introduce any runtime overhead:
Each lambda object has its unique type. So, to pass a lambda to a non-template function or to store them for later use, we can enter std::function. Here are some explanations about std::functions:
An exception is a problem that arises during the execution of a program. A C++ exception is a response to an exceptional circumstance that arises while a program is running, such as an attempt to divide by zero.
Exceptions provide a way to transfer control from one part of a program to another. C++ exception handling is built upon three keywords: try, catch, and throw.
Assuming a block will raise an exception, a method catches an exception using a combination of the try and catch keywords. A try/catch block is placed around the code that might generate an exception. Code within a try/catch block is referred to as protected code, and the syntax for using try/catch looks like the following:
try
{
// protected code
}catch( ExceptionName e1 )
{
// catch block
}catch( ExceptionName e2 )
{
// catch block
}catch( ExceptionName eN )
{
// catch block
}
You can list down multiple catch statements to catch different type of exceptions in case your try block raises more than one exception in different situations.
Exceptions can be thrown anywhere within a code block using throw statements. The operand of the throw statements determines a type for the exception and can be any expression and the type of the result of the expression determines the type of exception thrown.
Following is an example of throwing an exception when dividing by zero condition occurs:
double division(int a, int b) {
if( b == 0 ) {
throw “Division by zero condition!”;
}
return (a/b);
}
The catch block following the try block catches any exception. You can specify what type of exception you want to catch and this is determined by the exception declaration that appears in parentheses following the keyword catch.
try {
// protected code
}catch( ExceptionName e ) {
// code to handle ExceptionName exception
}
Above code will catch an exception of ExceptionName type. If you want to specify that a catch block should handle any type of exception that is thrown in a try block, you must put an ellipsis, …, between the parentheses enclosing the exception declaration as follows:
try {
// protected code
}catch(…) {
// code to handle any exception
}
The following is an example, which throws a division by zero exception and we catch it in catch block.
#include <iostream>
using namespace std;
double division(int a, int b) {
if( b == 0 ) {
throw “Division by zero condition!”;
}
return (a/b);
}
int main () {
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
Because we are raising an exception of type const char*, so while catching this exception, we have to use const char* in catch block. If we compile and run above code, this would produce the following result:
Division by zero condition!
C++ provides a list of standard exceptions defined in <exception> which we can use in our programs. These are arranged in a parent-child class hierarchy shown below:
Here is the small description of each exception mentioned in the above hierarchy:
Exception | Description |
std::exception | An exception and parent class of all the standard C++ exceptions. |
std::bad_alloc | This can be thrown by new. |
std::bad_cast | This can be thrown by dynamic_cast. |
std::bad_exception | This is useful device to handle unexpected exceptions in a C++ program |
std::bad_typeid | This can be thrown by typeid. |
std::logic_error | An exception that theoretically can be detected by reading the code. |
std::domain_error | This is an exception thrown when a mathematically invalid domain is used |
std::invalid_argument | This is thrown due to invalid arguments. |
std::length_error | This is thrown when a too big std::string is created |
std::out_of_range | This can be thrown by the at method from for example a std::vector and std::bitset<>::operator[](). |
std::runtime_error | An exception that theoretically can not be detected by reading the code. |
std::overflow_error | This is thrown if a mathematical overflow occurs. |
std::range_error | This is occured when you try to store a value which is out of range. |
std::underflow_error | This is thrown if a mathematical underflow occurs. |
You can define your own exceptions by inheriting and overriding exception class functionality. Following is the example, which shows how you can use std::exception class to implement your own exception in standard way:
#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception {
const char * what () const throw () {
return “C++ Exception”;
}
};
int main() {
try {
throw MyException();
}catch(MyException& e) {
std::cout << “MyException caught” << std::endl;
std::cout << e.what() << std::endl;
} catch(std::exception& e) {
//Other errors
}
}
This would produce the following result:
MyException caught
C++ Exception
Here, what() is a public method provided by exception class and it has been overridden by all the child exception classes. This returns the cause of an exception.
INTRODUCTION-WHY CONCURRENCY
IS NECESSARY
CONCURRENCY INTRODUCED TO C++
Original C++ Standard was published in 1998 only support single thread programming.
The new C++ Standard (referred to as C++11 or C++0x) was published in 2011. It will acknowledge the existence of multithreaded programs. Memory models for concurrency is also introduced
WHY WRITE CONCURRENT PROGRAMS
Dividing a problem into multiple executing threads is an important programming technique.
Multiple executing threads may be the best way to describe a problem.
With multiple executing threads, we can write highly efficient program by taking advantage of any parallelism available in computer system.
CONCURRENCY REQUIREMENT ON PROGRAMMING LANGUAGE
Thread creation – be able to create another thread of control.
Thread synchronization – be able to establish timing relationships among threads.
One thread waits until another thread has reached a certain point in its code.
One threads is ready to transmit information while the other is ready to receive the message, simultaneously.
Thread communication – be able to correctly transmit data among threads.
THREAD CREATION
C++11 introduced a new thread library including utilities for starting and managing threads.
Creating an instance of std::thread will automatically start a new thread.
Two thread will be created. The main thread will launch a new thread when it encounter the code std::thread th( ) to executive the function threadFucntion();
The join function here is to force the current thread to wait for the thread to th finish. Otherwise the main function may exit without the thread th finished.
CRITICAL SECTION
Data are usually shared between threads. There is a problem when multiple threads attempting to operate on the same object simultaneously.
If the operation is atomic(not divisible) which means no other thread can modify any partial results during the operation on the object, then it is safe. Otherwise, we are in a race condition. a critical section is a piece of code that accesses a shared resource (data structure or device) that must not be concurrently accessed by more than one thread of execution
Preventing simultaneous execution of critical section by multiple thread is called mutual exclusion.
EXAMPLE
Shared objects between threads will lead synchronization issues. For example
5 threads created try to increase the counter 5000 times. This program has a synchronization problem. Here are some result obtained on my computer:
24138
20326
23345
25000
17715
It is not the same every time.
USING ATOMIC TYPES
C++11 concurrency library introduces atomic types as a template class: std::atomic. You can use any type you want with the template and the operation on that variable will be atomic and so thread-safe.
std::atomic<Type> object.
Different locking technique is applied according to the data type and size.
lock-free technique: integral types like int, long, float. It is much faster than mutexes technique.
Mutexes technique: for big type(such as 2MB storage). There is no performance advantage for atomic type over mutexes.
SYNCHRONIZATION BETWEEN THREADS
Except for protecting shared data, we also need to synchronization action on separate threads.
In C++ Standard Library, conditional variables and futures are provided to handle synchronization problems.
The condition_variable class is a synchronization primitive that can be used to block a thread, or multiple threads at the same time, until:
a notification is received from another thread
a timeout expires
Any thread that intends to wait on std::condition_variable has to acquire a std::unique_lock first. The wait operations atomically release the mutex and suspend the execution of the thread. When the condition variable is notified, the thread is awakened, and the mutex is reacquired.
MORE ABOUT UNIQUE_LOCK
The condition variables require std::unique_lock rather than the std::lock_quard — the waiting thread must unlock the mutex while it is waiting , the lock it again afterwards and the std::lock_guard does not provide such flexibility.
The flexibility to unlock a std::unique_lock is not just used for the call to wait() , it is also used once we’ve got the data to process, but before processing it (#6): processing data can potentially be a time-consuming operation, and as we saw in chapter 3, it is a bad idea to hold a lock on a mutex for longer than necessary.
ONE-OFF EVENT WITH FUTURES
If a thread needs to wait for a specific one-off event, then it obtains a future representing this event. The thread can poll the future to see if the event has occurred while performing some other task.
Two sorts of futures templates in C++ Standard Library.
std::unique_furture<> — the instance is the only one that refers to its associated event.
std::shared_future<> — multiple instances of it may refer to the same event. All the instance become ready at the same time, and they may all access any data associated with the event.
MEMORY MODEL
Two aspects to the memory model:
the basic structural aspects — how things are laid out in memory
Every variable is an object, including those that are members of other objects.
Every object occupies at least one memory location.
Variables of fundamental type such as int or char are exactly one memory location, whatever their size, even if they’re adjacent or part of an array.
Adjacent bit fields are part of the same memory location.
The concurrency aspects
If there is no enforced ordering between two accesses to a single memory location from separate threads, these accesses is not atomic,
if one or both accesses is a write, this is a data race, and causes undefined behaviour.
OPERATIONS ORDERS
Each of the operations on atomic types has an optional memory-ordering argument that be used to specify the required memory-ordering semantics. These operations can be divided into three categories:
Store operation, which can have memory_order_relaxed, memorey_order_release or memory_order_seq_cst ordering
Load operations, which can have memory_order_relaxed, memory_order_consume, memory_order_acquire, or memory_order_seq_cst ordering
Read-modify-write operations, which can have memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, or memory_order_seq_cst ordering
CONCLUSION
C++ committee introduced the concurrency into C++0X and C++11 make it support multi-threads which make C++ a adaptive to the current programming style.
To make concurrency possible, language should support threads launch, threads synchronization and threads communication.
The basic problem in concurrency is how to protected shared data and synchronize threads. Mutexes and atomic template are the solution to race conditions.
Lower level control based on memory models allow us to clear the semantic meaning in concurrency operation
The concept of object-oriented programming had its roots in SIMULA 67 but was not fully developed until the evolution of Smalltalk resulted in Smalltalk 80 (in 1980, of course). Indeed, some consider Smalltalk to be the base model for a purely object-oriented programming language. A language that is object oriented must provide support for three key language features: abstract data types, inheritance, and dynamic binding of method calls to methods. Abstract data types were discussed in detail in Chapter 11, so this chapter focuses on inheritance and dynamic binding.
There are a few principle concepts that form the foundation of object-oriented programming:
This is the basic unit of object oriented programming. That is both data and function that operate on data are bundled as a unit called as object.
When you define a class, you define a blueprint for an object. This doesn’t actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object.
There are several ways a derived class can differ from its parent. Following are the most common differences between a parent class and its subclasses:
Data abstraction refers to, providing only essential information to the outside world and hiding their background details, i.e., to represent the needed information in program without presenting the details.
For example, a database system hides certain details of how data is stored and created and maintained. Similar way, C++ classes provides different methods to the outside world without giving internal detail about those methods and data.
Encapsulation is placing the data and the functions that work on that data in the same place. While working with procedural languages, it is not always clear which functions work on which variables but object-oriented programming provides you framework to place the data and the relevant functions together in the same object.
One of the most useful aspects of object-oriented programming is code reusability. As the name suggests Inheritance is the process of forming a new class from an existing class that is from the existing class called as base class, new class is formed called as derived class.
This is a very important concept of object-oriented programming since this feature helps to reduce the code size.
As a simple example of inheritance, consider the following: Suppose we have a class named Vehicles, which has variables for year, color, and make. A natural specialization, or subclass, of this would be Truck, which could inherit the variables from Vehicle, but would add variables for hauling capacity and number of wheels.
One disadvantage of inheritance as a means of increasing the possibility of reuse is that it creates dependencies among the classes in an inheritance hierarchy. This result works against one of the advantages of abstract data types, which is that they are independent of each other. Of course, not all abstract data types must be completely independent.
But in general, the independence of abstract data types is one of their strongest positive characteristics. However, it may be difficult, if not impossible, to increase the reusability of abstract data types without creating dependencies among some of them. Furthermore, in many cases, the dependencies naturally mirror dependencies in the underlying problem space.
The ability to use an operator or function in different ways in other words giving different meaning or functions to the operators or functions is called polymorphism. Poly refers to many. That is a single function or an operator functioning in many ways different upon the usage is called polymorphism.
The concept of overloading is also a branch of polymorphism. When the exiting operator or function is made to operate on new data type, it is said to be overloaded.
A number of issues must be considered when designing the programming language features to support inheritance and dynamic binding. Those that we consider most important are discussed in this section.
The Exclusivity of Objects
A language designer who is totally committed to the object model of computation designs an object system that subsumes all other concepts of type. Everything, from a simple scalar integer to a complete software system, is an object in this mind-set. The advantage of this choice is the elegance and pure uniformity of the language and its use.
The primary disadvantage is that simple operations must be done through the message-passing process, which often makes them slower than similar operations in an imperative model, where single machine instructions implement such simple operations. In this purest model of objectoriented computation, all types are classes. There is no distinction between predefined and user-defined classes. In fact, all classes are treated the same way and all computation is accomplished through message passing.
One alternative to the exclusive use of objects that is common in imperative languages to which support for object-oriented programming has been added is to retain the complete collection of types from a traditional imperative programming language and simply add the object typing model. This approach results in a larger language whose type structure can be confusing to all but expert users.
Another alternative to the exclusive use of objects is to have an imperative style type structure for the primitive scalar types, but implement all structured types as objects. This choice provides the speed of operations on primitive values that is comparable to those expected in the imperative model. Unfortunately, this alternative also leads to complications in the language. Invariably, nonobject values must be mixed with objects. This creates a need for so-called wrapper classes for the nonobject types, so that some commonly needed operations can be implemented as methods of the wrapper class. When such an operation is needed for a nonobject value, the value is converted to an object of the associated wrapper class and the appropriate method of the wrapper class is used. This design is a trade of language uniformity and purity for efficiency.
Single and Multiple Inheritance
Another simple issue is: Does the language allow multiple inheritance (in addition to single inheritance)? Maybe it’s not so simple. The purpose of multiple inheritance is to allow a new class to inherit from two or more classes. Because multiple inheritance is sometimes highly useful, why would a language designer not include it? The reasons lie in two categories: complexity and efficiency. The additional complexity is illustrated by several problems.
First, note that if a class has two unrelated parent classes and neither defines a name that is defined in the other, there is no problem. However, suppose a subclass named C inherits from both class A and class B and both A and B define an inheritable method named display. If C needs to reference both versions of display, how can that be done? This ambiguity problem is further complicated when the two parent classes both define identically named methods and one or both of them must be overridden in the subclass. Another issue arises if both A and B are derived from a common parent, Z, and C has both A and B as parent classes. This situation is called diamond or shared inheritance. In this case, both A and B should include Z’s inheritable variables. Suppose Z includes an inheritable variable named sum. The question is whether C should inherit both versions of sum or just one, and if just one, which one? There may be programming situations in which just one of the two should be inherited, and others in which both should be inherited.
The question of efficiency may be more perceived than real. In C++, for example, supporting multiple inheritance requires just one additional array access and one extra addition operation for each dynamically bound method call, at least with some machine architectures (Stroustrup, 1994, p. 270). Although this operation is required even if the program does not use multiple inheritance, it is a small additional cost.
The use of multiple inheritance can easily lead to complex program organizations. Many who have attempted to use multiple inheritance have found that designing the classes to be used as multiple parents is difficult. Maintenance of systems that use multiple inheritance can be a more serious problem, for multiple inheritance leads to more complex dependencies among classes. It is not clear to some that the benefits of multiple inheritance are worth the added effort to design and maintain a system that uses it.
Interfaces are an alternative to multiple inheritance. Interfaces provide some of the benefits of multiple inheritance but have fewer disadvantages.
Allocation and Deallocation of Objects
There are two design questions concerning the allocation and deallocation of objects. The first of these is the place from which objects are allocated. If they behave like the abstract data types, then perhaps they can be allocated from anywhere. This means they could be allocated from the run-time stack or explicitly created on the heap with an operator or function, such as new. If they are all heap dynamic, there is the advantage of having a uniform method of creation and access through pointer or reference variables. This design simplifies the assignment operation for objects, making it in all cases only a pointer or reference value change. It also allows references to objects to be implicitly dereferenced, simplifying the access syntax.
If objects are stack dynamic, there is a problem with regard to subtypes. If class B is a child of class A and B is a subtype of A, then an object of B type can be assigned to a variable of A type. For example, if b1 is a variable of B type and a1 is a variable of A type, then a1 = b1; is a legal statement. If a1 and b1 are references to heap-dynamic objects, there is no problem—the assignment is a simple pointer assignment. However, if a1 and b1 are stack dynamic, then they are value variables and, if assigned the value of the object, must be copied to the space of the target object. If B adds a data field to what it inherited from A, then a1 will not have sufficient space on the stack for all of b1. The excess will simply be truncated, which could be confusing to programmers who write or use the code. This truncation is called object slicing. The following example illustrates the problem.
class A {
int x;
. . .
};
class B : A {
int y;
. . .
}
The second question here is concerned with those cases where objects are allocated from the heap. The question is whether deallocation is implicit, explicit, or both. If deallocation is implicit, some implicit method of storage reclamation is required. If deallocation can be explicit, that raises the issue of whether dangling pointers or references can be created.
Dynamic and Static Binding
As we have discussed, dynamic binding of messages to methods is an essential part of object-oriented programming. The question here is whether all binding of messages to methods is dynamic. The alternative is to allow the user to specify whether a specific binding is to be dynamic or static. The advantage of this is that static bindings are faster. So, if a binding need not be dynamic, why pay the price?
Nested Classes
One of the primary motivations for nesting class definitions is information hiding. If a new class is needed by only one class, there is no reason to define it so it can be seen by other classes. In this situation, the new class can be nested inside the class that uses it. In some cases, the new class is nested inside a subprogram, rather than directly in another class.
The class in which the new class is nested is called the nesting class. The most obvious design issues associated with class nesting are related to visibility. Specifically, one issue is: Which of the facilities of the nesting class are visible in the nested class? The other main issue is the opposite: Which of the facilities of the nested class are visible in the nesting class?
C++ evolved from C and SIMULA 67, with the design goal of support for object-oriented programming while retaining nearly complete backward compatibility with C. C++ classes, as they are used to support abstract data types. C++ support for the other essentials of object-oriented programming is explored in this section. The whole collection of details of C++ classes, inheritance, and dynamic binding is large and complex. This section discusses only the most important among these topics, specifically, those directly related to the design issues.
C++ was the first widely used object-oriented programming language, and is still among the most popular. So, naturally, it is the one with which other languages are often compared. For both of these reasons, our coverage of C++ here is more detailed than that of the other example languages.
Introduction to Data Abstraction
Data abstraction refers to, providing only essential information to the outside world and hiding their background details, i.e., to represent the needed information in program without presenting the details.
Data abstraction is a programming (and design) technique that relies on the separation of interface and implementation.
Let’s take one real life example of a TV, which you can turn on and off, change the channel, adjust the volume, and add external components such as speakers, VCRs, and DVD players, BUT you do not know its internal details, that is, you do not know how it receives signals over the air or through a cable, how it translates them, and finally displays them on the screen.
Thus, we can say a television clearly separates its internal implementation from its external interface and you can play with its interfaces like the power button, channel changer, and volume control without having zero knowledge of its internals.
Now, if we talk in terms of C++ Programming, C++ classes provides great level of data abstraction. They provide sufficient public methods to the outside world to play with the functionality of the object and to manipulate object data, i.e., state without actually knowing how class has been implemented internally.
Classes in C++ language are based on C struct type and Simula 67 classes. All of the class instances of a class share a single copy of the member functions. Each instance of a class has its own copy of the class data members. Instances can be static, stack dynamic, or heap dynamic.
For example, your program can make a call to the sort() function without knowing what algorithm the function actually uses to sort the given values. In fact, the underlying implementation of the sorting functionality could change between releases of the library, and as long as the interface stays the same, your function call will still work.
In C++, we use classes to define our own abstract data types (ADT). You can use the cout object of class ostream to stream data to standard output like this:
#include <iostream>
using namespace std;
int main( ) {
cout << “Hello C++” <<endl;
return 0;
}
Here, you don’t need to understand how cout displays the text on the user’s screen. You need to only know the public interface and the underlying implementation of cout is free to change.
Access Labels Enforce Abstraction
In C++, we use access labels to define the abstract interface to the class. A class may contain zero or more access labels:
There are no restrictions on how often an access label may appear. Each access label specifies the access level of the succeeding member definitions. The specified access level remains in effect until the next access label is encountered or the closing right brace of the class body is seen.
Benefits of Data Abstraction
Data abstraction provides two important advantages:
By defining data members only in the private section of the class, the class author is free to make changes in the data. If the implementation changes, only the class code needs to be examined to see what affect the change may have. If data are public, then any function that directly accesses the data members of the old representation might be broken.
Data Abstraction Example:
Any C++ program where you implement a class with public and private members is an example of data abstraction. Consider the following example:
#include <iostream>
using namespace std;
class Adder {
public:
// constructor
Adder(int i = 0) {
total = i;
// interface to outside world
void addNum(int number) {
total += number;
}
// interface to outside world
int getTotal() {
return total;
};
private:
// hidden data from outside world
int total;
};
int main( ) {
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
cout << “Total ” << a.getTotal() <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Total 60
Above class adds numbers together, and returns the sum. The public members addNum and getTotal are the interfaces to the outside world and a user needs to know them to use the class. The private member total is something that the user doesn’t need to know about, but is needed for the class to operate properly.
Designing Strategy
Abstraction separates code into interface and implementation. So while designing your component, you must keep interface independent of the implementation so that if you change underlying implementation then interface would remain intact.
In this case whatever programs are using these interfaces, they would not be impacted and would just need a recompilation with the latest implementation.
Encapsulation
All C++ programs are composed of the following two fundamental elements:
Encapsulation is an Object Oriented Programming concept that binds together the data and functions that manipulate the data, and that keeps both safe from outside interference and misuse. Data encapsulation led to the important OOP concept of data hiding.
Data encapsulation is a mechanism of bundling the data, and the functions that use them and data abstraction is a mechanism of exposing only the interfaces and hiding the implementation details from the user.
C++ supports the properties of encapsulation and data hiding through the creation of user-defined types, called classes. We already have studied that a class can contain private, protected and public members. By default, all items defined in a class are private. For example:
class Box {
public:
double getVolume(void) {
return length * breadth * height;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
The variables length, breadth, and height are private. This means that they can be accessed only by other members of the Box class, and not by any other part of your program. This is one way encapsulation is achieved.
To make parts of a class public (i.e., accessible to other parts of your program), you must declare them after the public keyword. All variables or functions defined after the public specifier are accessible by all other functions in your program.
Making one class a friend of another exposes the implementation details and reduces encapsulation. The ideal is to keep as many of the details of each class hidden from all other classes as possible.
Programming languages, in particular C++, not only provide a set of basic operations and statements, but also a means to define our own operations and statements. We call the operations and statements that we define functions and procedures, respectively. Procedures and functions (subprograms) may have parameters. These represent the objects from our program that are used in the subprogram.
Functions are defined as follows:
int times (int x, int y) {
// Code
}
Procedures are defined similarly, but without delivering any result:
void factors (int x) {
// Code
}
Subprogram definitions may appear before or after the main program.
function can only be used if previously declared. A function can be declared and used before its code is defined.
Once a subprogram has been declared, it can be used. Functions are used as operations within expressions. Procedures are used as statements. Example:
i = times (3, i + 2) + 1; // function …
factors(i); // procedure …
Appropriate use of subprograms:
SUBPROGRAM WITH PARAMETER PASSING
When a subprogram is called, the arguments are passed to the subprogram, so that its code can be executed:
times (3, i + 2) + …
int times(int x, int y) { … }
Each argument must have the same type as its corresponding parameter. In general, any expression can be the argument of a subprogram:
double maximum (double a, double b);
…
z = maximum (x, y);
…
r = maximum (3, gcd(s – 4, i) + alpha);
…
m = maximum (x, maximum (y + 3, 2*Pi*radius));
An object (a variable) is associated with a value and a memory location. In C++, there are two methods for parameter passing:
void p (int x, int& y) { … }
times (3, i + 2)
is equivalent to:
int times (int x, int y) { x = 3; y = i + 2; int p = 0; … }
The effect of call-by-reference is that the parameter becomes the same object (variable) as the argument, i.e., the parameter becomes an alias of the argument.
Example: procedure to swap the value of two variables
void exchange (int& x, int& y) {
int z = x;
x = y;
y = z;
}
exchange (a, b);
Is equivalent to having:
void exchange (int& x, int& y) {
int z = a;
a = b;
b = z;
}