The statement. const Time noon( 12, 0, 0 );

Benzer belgeler
Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü

Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü

C++ Class larina baslangic. C++ Versus C Object-oriented Language C++ Structure dan Object Create etmek. Structure tanimlama.

const objects & const member functions const objects ve const functions Data Member Initializer List Data Member Initializer List

Maltepe Üniversitesi Bilgisayar Mühendisliği Bölümü BİL 203 Veri Yapıları ve Algoritmalar I

const objects & const member functions

Object-Oriented Programming Laboratuvar 10

Pros and Cons of Pointers. Pointers. Avantajlar. Dezavantajlar

WEEK 11 CME323 NUMERIC ANALYSIS. Lect. Yasin ORTAKCI.

Inheritance. Inheritance (turetim)

BTEP243 Ders 3. class Yazım Kuralı:

Object-Oriented Programming Laboratuvar 11

BMH-303 Nesneye Yönelik Programlama

BBS 514 YAPISAL PROGRAMLAMA (STRUCTURED PROGRAMMING)

Virtualmin'e Yeni Web Sitesi Host Etmek - Domain Eklemek

Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü

BBS 514 YAPISAL PROGRAMLAMA (STRUCTURED PROGRAMMING)

BİL-142 Bilgisayar Programlama II

13.3 Relationships Among Objects in an Inheritance Hierarchy

#ifndef COMPLEX_H #define COMPLEX_H

BBM Discrete Structures: Final Exam Date: , Time: 15:00-17:00

CmpE 320 Spring 2008 Project #2 Evaluation Criteria

1 - Type aliases (typedef / using)

Bölüm 6. Diziler (arrays) Temel kavramlar Tek boyutlu diziler Çok boyutlu diziler

BBM Discrete Structures: Midterm 2 Date: , Time: 16:00-17:30. Question: Total Points: Score:

#include <stdio.h> int main(void) { float sayi; float * p; p = &sayi; printf("deger girin:"); scanf("%f", p); printf("girilen deger:%f\n", *p);

10/17/2007 Nesneye Yonelik Programlama 3.1

Argumentative Essay Nasıl Yazılır?

C++ Dersi: Nesne Tabanlı Programlama

Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü

Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü ++ Bilişim Enstitüsü

Nesne Tabanlı Programlama

Unlike analytical solutions, numerical methods have an error range. In addition to this

Java da, tüm değişkenlerin kullanılmadan önce tanımlanması edilmesi gerekir. Bir değişken tanımlamanın temel gösterimi bu şekildedir:

C ++ Ders 6. Çoklubenzesim

Object-Oriented Oriented Design (OOD) Procedure Based Programlama. OOD Ana Ozellikleri

D-Link DSL 500G için ayarları

ÖRNEKTİR - SAMPLE. RCSummer Ön Kayıt Formu Örneği - Sample Pre-Registration Form

a, ı ı o, u u e, i i ö, ü ü

C++ Dersi: Nesne Tabanlı Programlama

C++ Giriş Ders 1 MSGSU Fizik Bölümü Ferhat ÖZOK Kullanılacak kaynak: Published by Juan Soulié

First Stage of an Automated Content-Based Citation Analysis Study: Detection of Citation Sentences

#include <stdio.h> int main(void) { FILE * dosya; dosya = fopen("soru1.txt", "w"); fprintf(dosya, "Merhaba Dunya!"); fclose(dosya); return 0; }

Bölüm 8 Nesne-Tabanlı Programlama

MM103 E COMPUTER AIDED ENGINEERING DRAWING I

Object-Oriented Programming Lab 4. - Sıcaklık değeri, Kelvin biriminde saklansın. Varsayılan sıcaklık değeri K olsun.

TEMPLATES. Binnur Kurt Bilgisayar Mühendisliği Bölümü İstanbul Teknik Üniversitesi. C++ ile Nesneye Dayalı Programlama 1

En kucuk calisabilir birime satetement denir Statements semicolon (;) ile sonlanir Yalniz basina ; null statement i ifade eder

C++ ile Nesneye Dayalı Programlama

BBC English in Daily Life

ATILIM UNIVERSITY Department of Computer Engineering

Ardunio ve Bluetooth ile RC araba kontrolü

Yarışma Sınavı A ) 60 B ) 80 C ) 90 D ) 110 E ) 120. A ) 4(x + 2) B ) 2(x + 4) C ) 2 + ( x + 4) D ) 2 x + 4 E ) x + 4


HTML 4. Bölüm. Doç. Dr. İsmail Rakıp Karaş Dersin Course Page:

Bölüm 4: İş Parçacıkları. Operating System Concepts with Java 8 th Edition

YEDİTEPE ÜNİVERSİTESİ MÜHENDİSLİK VE MİMARLIK FAKÜLTESİ

Newborn Upfront Payment & Newborn Supplement

YEDİTEPE ÜNİVERSİTESİ MÜHENDİSLİK VE MİMARLIK FAKÜLTESİ

Islington da Pratisyen Hekimliğinizi ziyaret ettiğinizde bir tercüman istemek. Getting an interpreter when you visit your GP practice in Islington

Bağlaç 88 adet P. Phrase 6 adet Toplam 94 adet

"Şirket" Sunucusu ve Başarı Mobile Arasındaki HTTP Veri Aktarımı için Etkileşim Teknik Protokolü

Java dili, aşağıdakiler de dahil olmak üzere çok çeşitli denetleyici türlerine sahiptir.

BİL-142 Bilgisayar Programlama II

Programlamaya Giriş Karar Yapıları, Tekrarlı İfadeler(Döngüler)

Yazılım Kodlama ve İ simlendirme Standartları v1.0

Delta Pulse 3 Montaj ve Çalıstırma Kılavuzu.

Veri Yapıları ve Algoritmalar dönem

Do not open the exam until you are told that you may begin.

C++ Statements. { ve } arasında ifade edilen bir dizi statement bir compound statement (birleşik ifade) oluşturur.

C++ Dersi: Nesne Tabanlı Programlama

Cases in the Turkish Language

Present continous tense

HIGH SPEED PVC DOOR INSTALLATION BOOK

Ne zaman operator overloading yapilir. Operator Overloading

FBEB-512. C++ ile Nesne Tabanlı Programlama. Güz (5. Hafta)

BBM Discrete Structures: Final Exam - ANSWERS Date: , Time: 15:00-17:00

Bölüm 10 - Yapılar, Birlikler, Bit İşleme ve Sayma Sabitleri (Enumarations)

KONU 7: DOSYA İŞLEME ( File Processing )

FINITE AUTOMATA. Mart 2006 Ankara Üniversitesi Bilgisayar Mühendisliği 1

public static int Toplam int x, int y

"IF CLAUSE KALIPLARI"

5İ Ortak Dersler. İNGİLİZCE II Okutman Aydan ERMİŞ

Do not open the exam until you are told that you may begin.

12. HAFTA BLM323 SAYISAL ANALİZ. Okt. Yasin ORTAKCI.

TEST RESULTS UFED, XRY and SIMCON

Immigration Studying. Studying - University. Stating that you want to enroll. Stating that you want to apply for a course.

ZTM112 BİLGİSAYAR DESTETEKLİ ÇİZİM TEKNİĞİ

PROGRAMLAMAYA GİRİŞ DERS 2

Yaz okulunda (2014 3) açılacak olan (Calculus of Fun. of Sev. Var.) dersine kayıtlar aşağıdaki kurallara göre yapılacaktır:

C++ Dersi: Nesne Tabanlı Programlama

8. SINIF KAZANIM TESTLERİ 1.SAYI. Ar-Ge Birimi Çalışmasıdır ŞANLIURFA İL MİLLİ EĞİTİM MÜDÜRLÜĞÜ DİZGİ & TASARIM İBRAHİM CANBEK MEHMET BOZKURT

C++ Dersi: Nesne Tabanlı Programlama

WEEK 4 BLM323 NUMERIC ANALYSIS. Okt. Yasin ORTAKCI.

İZDÜŞÜM. İzdüşümün Tanımı ve Önemi İzdüşüm Metodları Temel İzdüşüm Düzlemleri Noktanın İzdüşümü Doğrunun İzdüşümü Düzlemlerin İz Düşümleri

Lambda İfadeleri (Lambda Expressions)

C++0x - Sağ Taraf Değerine Bağlanan Referanslar (Rvalue References)

IDENTITY MANAGEMENT FOR EXTERNAL USERS

Standard Template Library

MOBIL UYGULAMA GELIŞTIRME

Transkript:

1 - const (Constant) Objects and const Member Functions Some objects need to be modifiable and some do not. You may use keyword const to specify that an object is not modifiable and that any attempt to modify the object should result in a compilation error. The statement const Time noon( 12, 0, 0 ); declares a const object noon of class Time and initializes it to 12 noon.(const bir object(time class ının bir instance ı) declare edildi.ve initialize edildi.) Software Engineering Observation 10.1 Attempts to modify a const object are caught at compile time rather than causing execution-time errors.(const bir object i değiştirmeye çalışma girişimi compile time da yakalanır,dolayısıyla compile time error olur.) 2 - Performance Tip 10.1 Declaring variables and objects const when appropriate can improve performance compilers can perform optimizations on constants that cannot be performed on variables. (Uygun yerlerde const bir object veya variable declare etmek performance ı arttırır. Çünkü compiler variable lar üzerinde gerçekleştiremediği bazı optimization ları constant lar üzerinde gerçekleştirebilir.) 3 - C++ disallows member function calls for const objects unless the member functions themselves are also declared const. This is true even for get member functions that do not modify the object. (C++, const object lerin, const olmayan member function larını çağırmaya,invoke etmeye izin vermez. Yani const bir object in,nonconst bir get() member function ı olsa, bu get() fonksiyonu object i modify etmese bile, çağırılamaz. Çünkü modify edilip edilmemesine bakılmaksızın, const object in içindeki hiçbir nonconst function ve variable çağırılamaz.) 1

A member function is specified as const both in its prototype by inserting the keyword const after the function s parameter list and, in the case of the function definition, before the left brace that begins the function body. const bir member function hem declare edilirken hem de define edilirken, const keyword aşağıda gösterilen yerlere konulur. int gethour() const; // function declare edilirken const böyle kullanilir. int Time::getHour() const // function define edilirken const böyle kullanılır.... 4 - Common Programming Error 10.1 Defining as const a member function that modifies a data member of the object is a compilation error.(object i modify eden bir member function ı const olarak tanimlamak compilation error a neden olur. Non-const bir object için de böyledir bu durum, const bir object için de böyledir. Zaten daha önce ne demiştik, const object in içindeki bir member function ı bu function object i modify etmiyor olsa bile çağıramayız demiştik.) 5 - Common Programming Error 10.2 Defining as const a member function that calls a non-const member function of the class on the same object is a compilation error. Class A //aynı obje içindeki const function icinde, non-const function cagirilirsa compile error olur. int f() const 2

g(); // compile error int g()... Şuradan aklında kalsın: Const object in, non-const member function ını çağıramazsın. Const member function body sinde, non-const member function ı(aynı object in) çağıramazsın. Common Programming Error 10.3 Invoking a non-const member function on a const object is a compilation error.(const bir object içinde nonconst bir member function invoke etmek compile error a neden olur.) Software Engineering Observation 10.2 A const member function can be overloaded with a non-const version. The compiler chooses which overloaded member function to use based on the object on which the function is invoked. If the object is const, the compiler uses the const version. If the object is not const, the compiler uses the non-const version. (const member function ı nonconst versiyonu ile overload edebiliriz. Compiler hangi overloaded member function ı seçeceğine nasıl karar verir? Function ın çağırıldığı object e göre karar verir. Açıklayalım. Object const ise, const versiyonlu member function çağırılır. Object non-const ise, non-const versiyonlu member function çağırılır.) 6 - An interesting problem arises for constructors and destructors, each of which typically modifies objects. A constructor must be allowed to modify an object so that the object can be initialized properly. A destructor must be able to perform its termination housekeeping chores before an object s memory is reclaimed by the system. 3

(Constructor ları veya destructor ları const diye declare etmek compilation error a neden olur. Constructor const olamaz çünkü object i initialize etmek ile görevlidir,object i modify edebilme yeteneğine sahip olmalıdır.destructor da benzer şekilde.) Common Programming Error 10.4 Attempting to declare a constructor or destructor const is a compilation error. Defining and Using const Member Functions The program of Figs. 10.1 10.3 modifies class Time of Figs. 9.8 9.9 by making its get functions and printuniversal function const. In the header Time.h (Fig. 10.1), lines 19 21 and 24 now include keyword const after each function prototype s parameter list. The corresponding definition of each function in Fig. 10.2 (lines 53, 59, 65 and 71, respectively) also specifies keyword const after each function s parameter list. 7 - // Fig. 10.1: Time.h // Time class definition with const member functions. // Member functions defined in Time.cpp. #ifndef TIME_H #define TIME_H class Time public: Time( int = 0, int = 0, int = 0 ); // default constructor // set functions void settime( int, int, int ); void sethour( int ); void setminute( int ); void setsecond( int ); 4

// get functions (normally declared const) int gethour() const; // return hour int getminute() const; // return minute int getsecond() const; // return second // print functions (normally declared const) void printuniversal() const; // print universal time void printstandard(); // print standard time (should be const) private: int hour; int minute; // 0-59 int second; // 0-59 ; // end class Time #endif Figure 10.1 Time class definition with const member functions. // Fig. 10.2: Time.cpp // Time class member-function definitions. #include <iostream> #include <iomanip> #include <stdexcept> #include "Time.h" // include definition of class Time using namespace std; constructor function to initialize private data; // calls member function settime to set variables; // default values are 0 (see class definition) Time::Time( int hour, int minute, int second ) settime( hour, minute, second ); // end Time constructor 5

// set hour, minute and second values void Time::setTime( int hour, int minute, int second ) sethour( hour ); setminute( minute ); setsecond( second ); // end function settime // set hour value void Time::setHour( int h ) if ( h >= 0 && h < 24 ) hour = h; else throw invalid_argument( "hour must be 0-23" ); // end function sethour // set minute value void Time::setMinute( int m ) if ( m >= 0 && m < 60 ) minute = m; else throw invalid_argument( "minute must be 0-59" ); // end function setminute // set second value void Time::setSecond( int s ) if ( s >= 0 && s < 60 ) second = s; else throw invalid_argument( "second must be 0-59" ); 6

// end function setsecond int Time::getHour() const // get functions should be const return hour; int Time::getMinute() const return minute; int Time::getSecond() const return second; // print Time in universal-time format (HH:MM:SS) void Time::printUniversal() const cout << setfill( '0' ) << setw( 2 ) << hour << ":" << setw( 2 ) << minute << ":" << setw( 2 ) << second; // end function printuniversal // print Time in standard-time format (HH:MM:SS AM or PM) void Time::printStandard() // note lack of const declaration cout << ( ( hour == 0 hour == 12 )? 12 : hour % 12 ) << ":" << setfill( '0' ) << setw( 2 ) << minute << ":" << setw( 2 ) << second << ( hour < 12? " AM" : " PM" ); // end function printstandard Fig. 10.2 Time class member-function definitions. (Part 3 of 3.) // Fig. 10.3: fig10_03.cpp 7

// Attempting to access a const object with non-const member functions. #include "Time.h" // include Time class definition int main() Time wakeup( 6, 45, 0 ); // non-constant object const Time noon( 12, 0, 0 ); // constant object // OBJECT MEMBER FUNCTION wakeup.sethour( 18 ); // non-const non-const noon.sethour( 12 ); // const non-const wakeup.gethour(); // non-const const noon.getminute(); // const const noon.printuniversal(); // const const noon.printstandard(); // const non-const // end main Fig. 10.3 const objects and const member functions. Output: Microsoft Visual C++ compiler error messages: C:\cpphtp8_examples\ch10\Fig10_01_03\fig10_03.cpp(13) : error C2662: 'Time::setHour' : cannot convert 'this' pointer from 'const Time' to 'Time &' Conversion loses qualifiers C:\cpphtp8_examples\ch10\Fig10_01_03\fig10_03.cpp(20) : error C2662: 'Time::printStandard' : cannot convert 'this' pointer from 'const Time' to 'Time &' Conversion loses qualifiers 8

- Figure 10.3 deki main() fonksiyonunda 2 tane Time object create edilir, bu object lerden noon const dur, wakeup ise non-const dur. - Non-const member function lar olan sethour ve printstandard noon object inden invoke edilir. Her iki invocation için de compiler error mesajı generate eder. - Örnekteki diğer 3 kombinasyon ise hatasız bir şekilde çalışır. Şu kombinasyonlar: o a non-const member function on a non-const object o a const member function on a non-const object o a const member function on a const object - non const member functions called on a const object : compile time error message generate edilir 8 - A constructor must be a non-const member function, but it can still be used to initialize a const object. (Bir constructor non-const bir member function olmak zorundadır. Ancak bir constructor, const bir object i initialize etmek için kullanılabilir. Bunda bir sakınca yoktur. Figure 10.2 deki Time.cpp dosyasında, Time class ının constructor ı non-const olarak tanımlanmıştır. Zaten bir constructor const olarak tanımlanamaz. Ama bu constructor, const bir object initialize ederken kullanılabilir,bunda bir sakınca yoktur. Hatırla, const bir fonksiyonun içinden nonconst bir fonksiyon çağırılamıyordu, ancak const bir object i initialize ederken, non-const bir fonksiyon gibi düşünülen constructor çağırılabiliyor. const Time noon(12,0,0); //main in içinde Time object i create ve initialize ediliyor. Object const dur. Initialize edilirken kullanılan constructor non-const dur. ) - The Time constructor s definition (Fig. 10.2, lines 11 14) shows that it calls another non-const member function settime (lines 17 22) to perform the initialization of a Time object. Invoking a nonconst member function from the constructor call as part of the initialization of a const object is allowed. The constness of a const object is enforced 9

from the time the constructor completes initialization of the object until that object s destructor is called. ( Time constructon ının definition ına bakalım. Time constructor ının body sinden diğer bir non-const member function settime() çağırılıyor. Böylece Time object initialize ediliyor. Burada olduğu gibi, const bir object in constructor ının body si içinden, nonconst bir member function çağırılabilir, C++ buna izin verir. Bir object in constness olması(modify edilemez olması özelliği) ne zaman başlar? Constructor, object in initialize olması işlemini tamamlayınca başlar. Ne zamana kadar sürer peki bu const object in constness lığı? Bu object in destructor ı çağırılana kadar sürer. Yani object create edildikten sonra başlar constness özelliği. Dolayısıyla create edilmiş bir object in member larını çağırırken constness kurallarına uyuluyor mu diye dikkat etmemiz lazım. Bir object in constructor ı içinden ise const ve non-const istediğimiz şeyi çapırmak mümkündür. ) Line 20 in Fig. 10.3(Noon.printStandard(); showed below) generates a compilation error even though member function printstandard of class Time does not modify the object on which it s invoked. The fact that a member function does not modify an object is not sufficient to indicate that the function is a constant function the function must explicitly be declared const. (const Time noon(12,0,0); // object const olarak declare edildi. Noon.printStandard(); // const bir object in nonconst bir member function ı çapırılmış. Time class ının printstandard() member function ı invoke edildiği object i modify etmemesine rağmen, bu satır compile error verir. Bir member function ın, içinde bulunduğu object i modify etmiyor olması, bu function ın constant function olduğu anlamına gelmez kesinlikle, constant olması istenen fonksiyon explicit bir şekilde const keyword kullanılarak declare edilmelidir. Bu dediğimi iyi anla. ) 9 - Initializing a const Data Member with a Member Initializer (Member initializer kullanarak const data member larını initialize etmek) All data members can be initialized using member initializer syntax, but const data members and data members that are references must be initialized using member initializers. Bu chapter içinde birazdan, member object lerin de aynı şekilde inialize edilmek zorunda 10

olduklarını göreceğiz. Later in this chapter, we ll see that member objects must be initialized this way as well. (member initializer syntax ı kullanılarak tüm data member ları initialize edilebilir. Ama const data member ları bu sentax kullanılarak initialize edilmek zorundadır. Member objects ne demek la? ) (Aşağıdaki programda kalın kırmızı ile yazdığım yerlere dikkat et. Increment class ının constructor ında member initializer kullanılarak, const ve nonconst data member lar initialize ediliyor.) // Fig. 10.4: Increment.h // Definition of class Increment. #ifndef INCREMENT_H #define INCREMENT_H class Increment public: Increment( int c = 0, int i = 1 ); // default constructor // function addincrement definition void addincrement() count += increment; // end function addincrement void print() const; // prints count and increment private: int count; const int increment; // const data member ; // end class Increment 11

#endif Fig. 10.4 Increment class definition containing non-const data member count and const data member increment. // Increment.cpp #include <iostream> #include "Increment.h" // include definition of class Increment using namespace std; Increment::Increment( int c, int i ) : count (c), // nonconst member(c) için initializer increment(i) // const member(increment) için zorunlu initializer // empty body // print count and increment values void Increment::print() const cout << "count = " << count << ", increment = " << increment << endl; Fig. 10.5 Member initializer used to initialize a constant of a built-in data type. // fig10_06.cpp // Program to test class Increment. #include <iostream> #include "Increment.h" // include definition of class Increment using namespace std; int main() 12

Increment value( 10, 5 ); cout << "Before incrementing: "; value.print(); for ( int j = 1; j <= 3; ++j ) value.addincrement(); cout << "After increment " << j << ": "; value.print(); // end for // end main Fig. 10.6 Invoking an Increment object s print and addincrement member functions. Output: Before incrementing: count = 10, increment = 5 After increment 1: count = 15, increment = 5 After increment 2: count = 20, increment = 5 After increment 3: count = 25, increment = 5 The constructor definition (Fig. 10.5, lines 9 14) uses a member initializer list to initialize class Increment s data members non-const integer count and const integer increment (declared in lines 19 20 of Fig. 10.4). (Yukarıdaki constructor definition ı member initializer list kullanarak Increment class ının data member ları olan şunları initialize eder : - non-const integer count - const integer increment ) Member initializers appear between a constructor s parameter list and the left brace that begins the constructor s body. The member initializer list is separated from the parameter list with a colon (:). Each member initializer consists of the data member name followed by parentheses containing the member s initial value. In this example, count is initialized with the value of constructor parameter c and increment is initialized with the value of constructor parameter i. Multiple member initializers are separated by commas. Also, the member initializer list executes before the body of the constructor executes. 13

(Member initializer lar constructor ın parameter list i ve left brace() arasına gelir. parameter list den sonra colon(iki nokta üst üste) koyulur. Sonra member initializer list yazılır. Herbir member initializer şunu içerir: Önce data member name(class ın data memberları) yazılır. Sonra parantez içinde ilgili member ın initial value sü(ilk değeri) yazılır Increment::Increment( int c, int i ) : count (c), increment(i) // empty body ) Yukarıdaki örneği inceleyelim: count = c increment = i Birden fazla member initializer olduğu için bunlar birbirlerinden virgül ile ayrılır. Ayrıca; önce member initializer list execute edilir(çalıştırılır), sonra constructor ın body si execute edilir(çalıştırılır). Software Engineering Observation 10.3 A const object cannot be modified by assignment, so it must be initialized. When a data member of a class is declared const, a member initializer must be used to provide the constructor with the initial value of the data member for an object of the class. The same is true for references. (const bir object assignment kullanılarak modify edilemez, dolayısıyla const bir object initialize edilmek zorundadır. Bir class ın data member ı(mesela Time class ının increment data member ı) const olarak declare edilirse, bu class dan bir object create ederken const data member larını initialize etmek amacıyla member initializer kullanılmak zorundadır. Aynı kural reference lar için de geçerlidir.) 14

10 - Why Is Function print Declared const? Function print (Fig. 10.5, lines 17 20) is declared const. It might seem strange to label this function const, because a program probably will never have a const Increment object. However, it s possible that a program will have a const reference to an Increment object or a pointer to const that points to an Increment object. (Peki en son incelediğimiz koddaki print fonksyionu neden const olarak declare edildi,bunu düşünelim. Bu programda belki de hiçbir zaman const Increment object create etmeyeceğiz. Increment class ının amacı bu değil çünkü. Ama buna rağmen, print fonksiyonunu const yapmak ilk başta ilginç gibi gelebilir. İşin doğrusu budur. Nedenini açıklayalım. Programımız şunlara sahip olabilir: - const reference to an Increment - pointer to const that points to an Increment object ) Typically, this occurs when - objects of class Increment are passed to functions, or - objects of class Increment are returned from functions. In these cases, only class Increment s const member functions can be called through the reference or pointer. Thus, it s reasonable to declare function print as const, doing so prevents errors in these situations where an Increment object is treated as a const object. ( Bu genellikle, - Increment object bir fonksiyon a pass edildiğinde(argument olarak verildiğinde) olur, - Bir fonksiyondan return ederken olur Bu case lerde, reference veya pointer aracılığıyla, Increment object in sadece const member function ları çağırılabilir. Dolayısıyla, print fonksiyonunu const olarak declare etmek mantıklıdır. Böylece Increment object in const olarak treat edildiği(görüldüğü) durumlarda meydana gelebilecek muhtemel error ları önler. ) Error-Prevention Tip 10.1 (Muhtemel error ları önlemek için ipucu) 15

Declare as const all of a class s member functions that do not modify the object in which they operate. Occasionally this may seem inappropriate, because you ll have no intention of creating const objects of that class or accessing objects of that class through const references or pointers to const. Declaring such member functions const does offer a benefit, though. If the member function is inadvertently written to modify the object, the compiler will issue an error message. (class ın object i modify etmeyen tüm member function larını const olarak declare etmeliyiz. Bazen bu uygun değil gibi gözükebilir, çünkü - bu class dan const object ler create etmek gibi bir amacınız yoktur, - const reference kullanarak bu object e erişmek gibi bir amacınız yoktur, - hatta pointers to const kullanarak bu class ın bu object lerine erişme amacınız da yoktur. Ancak bu gibi member function ları const olarak declare etmenin şöyle bir yararı vardır. Bu member function yanlışlıkla object i modify edecek bir şekilde yazılmışsa(implement edilmişse), compiler error verir, siz de hatanızın farkına varıp düzeltirsiniz.) Erroneously Attempting to Initialize a const Data Member with an Assignment Figure 10.7 shows the compilation errors caused by attempting to initialize const data member increment with an assignment statement in the Increment constructor s body rather than with a member initializer. (Eğer Increment class ının const data member ı olan increment, member initializer ile initialize edilmek yerine, Increment constructor ının body sinde assignment ile initialize edilmeye çalışılırsa, aşağıdaki gibi bir compile error alırız. ) Microsoft Visual C++ compiler error messages: (Microsoft Visual C++ da görülen erro mesajı böyledir) C:\cpphtp8_examples\ch10\consterror\Increment.cpp(10) : error C2758: 'Increment::increment' : must be initialized in constructor base/member initializer list C:\cpphtp8_examples\ch10\consterror\increment.h(20) : see declaration of 'Increment::increment' C:\cpphtp8_examples\ch10\consterror\Increment.cpp(12) : error C2166: l-value specifies const object 16

GNU C++ compiler error messages: (GNU C++ da görülen erro mesajı böyledir) Increment.cpp:9: error: uninitialized member 'Increment::increment' with 'const' type 'const int' Increment.cpp:12: error: assignment of read-only data-member 'Increment::increment' Fig. 10.7 Compilation errors generated by attempting to initialize a const data member in the constructor s body rather than in the member initializer list. (const data member ı constructor body içinden initialize etmeye kalkışırsak bu error mesajlarını alırız. ) Common Programming Error 10.5 Not providing a member initializer for a const data member is a compilation error. (const data member için member initializer provide etmemek, diğer bir deyişle const data member ı initialize etmemek, compilation error dır.) 10.3 Composition: Objects as Members of Classes An AlarmClock object needs to know when it s supposed to sound its alarm, so why not include a Time object as a member of the AlarmClock class? Such a capability is called composition and is sometimes referred to as a has-a relationship a class can have objects of other classes as members. (Elimizde bir AlarmClock object olduğunu düşünelim. Alarm ın ne zaman çalacağını bu object in bilmesi gerekir. Dolayısıyla, Time object in AlarmClock class ının bir member ı olması çok mantıklıdır. Time object bu durumda member object olur. Bu capability ye composition denir, diğer bir ifadeyle has-a relationship de denir. Yani bir class, diğer class ların instance(object) larını member olarak içerebilir. ) Software Engineering Observation 10.4 A common form of software reusability is composition, in which a class has objects of other classes as members. (Software reusability nin ortak yaygın bir biçimidir composition. Bir class başka bir class ın instance ına sahip olabilir.) Previously, we saw how to pass arguments to the constructor of an object we created in main. Now we show how an object s constructor can pass arguments to member-object constructors via member initializers. ( main() de bir object create ederken, object in constructor ına nasıl argument verdiğimizi öğrenmiştik. Şimdi ise bir object in constructor ının member initializer lar aracılığıyla, member-object constructor lara nasıl argument verdiğini(pass ettiğini) göreceğiz. 17

Yani bir object in constructor ını kullanarak, bu object in içerdiği başka bir object in constructor larına argument vereceğiz, bunu member initializer kullanarak yapacağız. ) Software Engineering Observation 10.5 Member objects are constructed in the order in which they re declared in the class definition (not in the order they re listed in the constructor s member initializer list) and before their enclosing class objects (sometimes called host objects) are constructed. (Member object ler, class definition da declare edildikleri sıraya göre construct edilirler. Constructor ın member initializer list indeki kullanıldıkları sıraya göre construct edilmezler, karıştırma! Ayrıca önce member object ler construct edilir, sonra enclosing class object(host object) construct edilir. ) Aşağıdaki inceleyeceğimiz program composition ı gösterir. Date ve Empleyee isimli 2 tane class tanımlayacağız bu programda. Sırasıyla şu source kodları inceleyeceğiz : - Date.h, - Date,cpp, - Employee.h, - Employee.cpp - main.cpp Employee class ının definition ına bakalım, bu class 4 tane private data member içerir : - firstname - lastname - birthdate : this member is const object of class Date which contains private data members month, day and year ( bu data member, Date class ının bir object idir, const dur. 3 tane private data member içerir). - hiredate : this member is const object of class Date which contains private data members month, day and year ( Date class ının bir object idir, const dur. 3 tane private data member içerir ). The Employee constructor s header specifies that the constructor has four parameters (first, last, dateofbirth and dateofhire). The first two parameters are passed via member initializers to the string class constructor. The last two are passed via member initializers to the Date class constructor. ( Employee class ının constructor ının header ı şunu 4 tane parameter specify eder. 18

İlk 2 parameter, member initializer lar aracılığıyla, string class ının constructor ına verilir(pass edilir). Son 2 parameter, member initializer lar aracılığıyla, Date class ının constructor ına verilir(pass edilir). ) Employee::Employee( const string &first, const string &last, const Date &dateofbirth, const Date &dateofhire ) : firstname( first ), // initialize firstname lastname( last ), // initialize lastname birthdate( dateofbirth ), // initialize birthdate hiredate( dateofhire ) // initialize hiredate // somehing to write Source codes are below: // Fig. 10.8: Date.h // Date class definition; Member functions defined in Date.cpp #ifndef DATE_H #define DATE_H class Date public: static const int monthsperyear = 12; // number of months in a year Date( int = 1, int = 1, int = 1900 ); // default constructor void print() const; // print date in month/day/year format ~Date(); // provided to confirm destruction order private: int month; // 1-12 (January-December) int day; // 1-31 based on month int year; // any year ; #endif // utility function to check if day is proper for month and year int checkday( int ) const; // Fig. 10.9: Date.cpp // Date class member-function definitions. #include <iostream> #include <stdexcept> 19

#include "Date.h" // include Date class definition using namespace std; // constructor confirms proper value for month; calls // utility function checkday to confirm proper value for day Date::Date( int mn, int dy, int yr ) if ( mn > 0 && mn <= monthsperyear ) // validate the month month = mn; else throw invalid_argument( "month must be 1-12" ); year = yr; // could validate yr day = checkday( dy ); // validate the day // output Date object to show when its constructor is called cout << "Date object constructor for date "; print(); cout << endl; // end Date constructor // print Date object in form month/day/year void Date::print() const cout << month << '/' << day << '/' << year; // end function print // output Date object to show when its destructor is called Date::~Date() cout << "Date object destructor for date "; print(); cout << endl; // end ~Date destructor // utility function to confirm proper day value based on // month and year; handles leap years, too int Date::checkDay( int testday ) const static const int dayspermonth[ monthsperyear + 1 ] = 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ; // determine whether testday is valid for specified month if ( testday > 0 && testday <= dayspermonth[ month ] ) return testday; 20

// February 29 check for leap year if ( month == 2 && testday == 29 && ( year % 400 == 0 ( year % 4 == 0 && year % 100!= 0 ) ) ) return testday; throw invalid_argument( "Invalid day for current month and year" ); // end function checkday // Fig. 10.10: Employee.h // Employee class definition showing composition. // Member functions defined in Employee.cpp. #ifndef EMPLOYEE_H #define EMPLOYEE_H #include <string> #include "Date.h" // include Date class definition using namespace std; class Employee public: Employee( const string &, const string &, const Date &, const Date & ); void print() const; ~Employee(); // provided to confirm destruction order private: string firstname; // composition: member object string lastname; // composition: member object const Date birthdate; // composition: member object const Date hiredate; // composition: member object ; // end class Employee #endif // Fig. 10.11: Employee.cpp // Employee class member-function definitions. #include <iostream> #include "Employee.h" // Employee class definition #include "Date.h" // Date class definition using namespace std; // constructor uses member initializer list to pass initializer // values to constructors of member objects // constructor, member initializer list i kullanarak, initial değerleri 21 Employee Constructor s Member Initializer List The colon (:) following the Employee constructor s header begins the member initializer list. The member initializers specify the Employee constructor parameters being passed to the constructors of the string and Date data members. Parameters first, last, dateofbirth and dateofhire are passed to the constructors for objects firstname, lastname, birthdate and hiredate, respectively. Again, member initializers are separated by commas. (Employee class ının

// member object lerin constructor larına verir(pass eder). Employee::Employee( const string &first, const string &last, const Date &dateofbirth, const Date &dateofhire ) : firstname( first ), // initialize firstname lastname( last ), // initialize lastname birthdate( dateofbirth ), // initialize birthdate hiredate( dateofhire ) // initialize hiredate cout << "Employee object constructor: " << firstname << ' ' << lastname << endl; // end Employee constructor // print Employee object void Employee::print() const cout << lastname << ", " << firstname << " Hired: "; hiredate.print(); cout << " Birthday: "; birthdate.print(); cout << endl; // end function print // output Employee object to show when its destructor is called Employee::~Employee() cout << "Employee object destructor: " << lastname << ", " << firstname << endl; // end ~Employee destructor Date Class s Default Copy Constructor As you study class Date (Fig. 10.8), notice that the class does not provide a constructor that receives a parameter of type Date. So, why can the Employee constructor s member initializer list initialize the birthdate and hiredate objects by passing Date object s to their Date constructors? As we mentioned in Chapter 9, the compiler provides each class with a default copy constructor that copies each data member of the constructor s argument object into the corresponding member of the object being initialized. Chapter 11 discusses how you can define customized copy constructors. (Date class ını inceleyelim. Bu class ın Date type ında bir parameter alan bir constructor ı olmadığını fark ederiz. Ama Employee class ının constructor ının member initializer list i(aşağıda verilen kodu incele), Date class ının constructor ına argument ler pass edebiliyor, bu 22

sayede birthdate ve hiredate object lerini initialize ediyor. Bu nasıl oluyor o zaman? Employee::Employee(..., const Date &dateofbirth, const Date &dateofhire ) : birthdate( dateofbirth ), // initialize birthdate hiredate( dateofhire ) // initialize hiredate... //Something to write Chapter 9 da ne öğrenmiştik? Compiler, herbir class için bir default copy constructor provide eder. Peki ne yapar default copy constructor? Constructor ın aldığı argument object lerin herbir data member larını, initialize edilecek object in corresponding member larına kopyalar. Chapter 11 de copy constructor ları kendi başımıza(manually) nasıl tanımlayabileceğimizi öğreneceğiz. ) Testing Classes Date and Employee Figure 10.12 creates two Date objects (lines 9 10) and passes them as arguments to the constructor of the Employee object created in line 11. (Aşağıdaki main fonksiyonunda 2 tane Date object create edilir ve bu object ler Employee class ının constructor ına verilir(pass edilir).) Line 14 outputs the Employee object s data. When each Date object is created in lines 9 10, the Date constructor displays a line of output to show that the constructor was called (see the first two lines of the sample output). ( 14. satırda, Employee object in data sı output edilir. Main() fonksiyonu içinde 9. Ve 10.satırlardaki herbir Date object create edildiğinde, Date constructor bir satırlık yazı output eder ekrana. ) [Note: Line 11 of Fig. 10.12 causes two additional Date constructor calls that do not appear in the program s output. (Main fonksiyonundaki 11.satır : Employee manager( "Bob", "Blue", birth, hire ); // Program ın output unda görünmeyen 2 tane daha Date constructor ının çağırılmasına neden olur. ) When each of the Employee s Date member object s is initialized in the Employee constructor s member initializer list, the default copy constructor for class Date is called. (Employee nin herbir Date member object i(birthdate ve HireDate), Employee constructor ının member initializer list inde initialize edildiğinde, Date class ının default copy constructor ı çağırılır. Employee::Employee(... const Date &dateofbirth, 23

const Date &dateofhire ) :... birthdate( dateofbirth ), // calls default copy constructor of class Date hiredate( dateofhire ) // calls default copy constructor of class Date // Something to write ) Since this constructor is defined implicitly by the compiler, it does not contain any output statements to demonstrate when it s called.] Bu constructor(default copy constructor) compiler tarafından implicitly define edildiği için, bu constructor çağırıldığı zaman stdout a yazan bir output statement içermez. Kendimiz define etmeyi öğrendiğimiz zaman içine cout yazıp, ne zaman çağırıldığını görebiliriz.] ) 1 // fig10_12.cpp 2 // composition example - member object içeren başka bir object 3 #include <iostream> 4 #include "Employee.h" // Employee class definition 5 using namespace std; 6 7 int main() 8 9 Date birth( 7, 24, 1949 ); 10 Date hire( 3, 12, 1988 ); 11 Employee manager( "Bob", "Blue", birth, hire ); 12 13 cout << endl; 14 manager.print(); 15 // end main Output: Date object constructor for date 7/24/1949 Date object constructor for date 3/12/1988 Employee object constructor: Bob Blue There are actually five constructor calls when an Employee is constructed - two calls to the string class s constructor, two calls to the Date class s default copy constructor and the call to the Employee class s constructor. ( Output da sadece 1 tane görünmesine rağmen, aslında 5 tane constructor call yapılır, Employee object construct edildiğinde. Blue, Bob Hired: 3/12/1988 Birthday: 7/24/1949 Employee object destructor: Blue, Bob Date object destructor for date 3/12/1988 Date object destructor for date 7/24/1949 Date object destructor for date 3/12/1988 Date object destructor for date 7/24/1949 24 Bunlardan 2 si string in class ının constructor ına yapılan call lardır : firstname(first), lastname(last) Bunlardan 2 si Date class ının default copy constructor ına yapılan call lardır. Bunlarda en sonuncusu ise output da da görünen Employee class ının constructor ına yapılan call dur. Hatırla bunlar class da declare edildikleri sıraya göre construct edilirler,member initializer list deki sıraya göre değil. Ayrıca önce member object lerin constructor ları çağırılır, sonra Employee constructor çağırılır. )

Here*********** Class Date and class Employee each include a destructor that prints a message when an object of its class is destructed. (Hem Date ve hem de Employee class'ının içerdiği destreuctor'lar, bu class'lardan bir object create edildiğinde bir mesaj yazdırırlar.böylece object'in destructor'ının çağırıldığını anlayabiliriz.) This enables us to confirm in the program output that objects are constructed from the inside out and destroyed in the reverse order, from the outside in (i.e., the Date member objects are destroyed after the Employee object that contains them). (Bu sayede, object'lerin içeriden dışarıya doğru construct edildiklerini, dışarıdan içeriye doğru(reverse) destruct edildiklerini onaylamış oluruz output'da gördüğümüz mesajlara göre. Bir diğer deyişle, önce member object olan Date class'ının object'i construct edilir. Sonra bu class'ı içeren(host class,enclosing class) Employee class'ı construct edilir. Destruct işlemi ise bunun tam tersi sıra ile olur. Önce enclosing class Employee destroy edilir,sonra member object Date class'ının object'i destroy edilir.) (Figure 10.12'deki program outputunun son 5 satırına bakalım: Employee object destructor: Blue, Bob output of destructor of Employee class Date object destructor for date 3/12/1988 destructor of Employee's member object birthdate Date object destructor for date 7/24/1949 destructor of Employee's member object hiredate Date object destructor for date 3/12/1988 dectructor of Date object birth Date object destructor for date 7/24/1949 dectructor of Date object hire ) These outputs confirm that the three objects created in main are destructed in the reverse of the order in which they were constructed. (main'de create edilen 3 object construct edildikleri sıranın tersi sırayla destroy edilirler. Bu output'lar da bunu onaylar.) These outputs confirm that the Employee object is destructed from the outside in i.e., the Employee destructor runs first (output shown five lines from the bottom of the output window), then the member objects are destructed in the reverse order from which they were constructed. (Employee object dışarıdan içeriye doğru destruct edilir. Yani önce Employee destructor'ı çalışır(sondan 5. output satırı), sonra member object'ler destruct edilirler(hangi sırayla? Construct edildikleri sıranın tersi sırayla).) Class string s destructor does not contain output statements, so we do not see the firstname and lastname objects being destructed. Again, Fig. 10.12 s output did not show the constructors running for member objects birthdate and hiredate, because these objects were initialized with the default Date class copy constructors provided by the compiler. 25

( string class'ının destructor'ı output statement(cout mesela) içermediği için, firstname ve lastname object'leri destruct edilirken, programın output'unda görünmüyor. Ayrıca birthdate ve hiredate member object'lerinin constructor'ları(compiler'ın provide ettiği default copy constructor) output statement içermediği için, output statement'da bunların çıktılarını da görmüyoruz. ) What Happens When I Do Not Use the Member Initializer List? If a member object is not initialized through a member initializer, the member object s default constructor will be called implicitly. Values, if any, established by the default constructor can be overridden by set functions. However, for complex initialization, this approach may require significant additional work and time. ( Bir member object, member initializer kullanılarak initialize edilmezse ne olur? Member object'in default constructor'ı implicitly çağırılır. Default constructor'lar ile belirlenen value'ler(değerler,tabi eğer değerler belirtilmişse) setter fonksiyonları ile override edilebilir. Ancak, complex initialization'lar(mesela çok fazla sayıda initialization varsa) için, bu yaklaşım önemli miktarda ekstra iş ve zaman alır. ) Common Programming Error 10.6 A compilation error occurs if a member object is not initialized with a member initializer and the member object s class does not provide a default constructor (i.e., the member object s class defines one or more constructors, but none is a default constructor). (Bir member object, member initializer kullanılarak initialize edilmezse, ve bu member object'in class'ı default constructor provide etmezse, compile error olur. Member object'in class'ında bir veya iki tane constructor tanımladık diyelim,ama bu constructor'lardan hiçbirisi default constructor olmasın diyelim, bu durumda bu class'ın default constructor'ı yoktur, enclosing class'ın constructor'ında bu member class'ı initialize etmezsek, compile error alırız.) Performance Tip 10.2 Initialize member objects explicitly through member initializers. This eliminates the overhead of doubly initializing member objects once when the member object s default constructor is called and again when set functions are called in the constructor body (or later) to initialize the member object. (Member object'leri, member initializer'lar kullanarak explicitly initialize edin. Böylece member object'leri iki kere initialize etme iş yükünden kurtulmuş oluruz (1. initialize,member object'in default constructor'ı çağırıldığında yapılır. 2. initialize, constructor body'de veya daha sonra set fonksiyonları çağırılarak member object initialize edildiğinde gerçekleşir). ) Software Engineering Observation 10.6 If a class member is an object of another class, making that member object public does not violate the encapsulation and hiding of that member object s private members. But, it does violate the encapsulation and hiding of the containing class s implementation, so member objects of class types should still be private, like all other data members. ( A class ı, B member class ının object ini içeriyor olsun. B object ini public yapmak, member object in private member larının hide edilmesi ve encapsulation kuralını bozmaz. Ama host class(enclosing class,içeren class, class A) ın implementation ının hide edilmesi ve encapsulate edilmesi kurallarını bozar. 26

Dolayısıyla, class type ındaki member object ler (class B mesela) diğer data member ları gibi, private olmalıdır. 10.4 Friend functions and Friend classes A friend function of a class is defined outside that class s scope, yet has the right to access the non-public (and public) members of the class. (Bir class ın friend fonksiyonu class ın scope unun dışında tanımlanır, ancak bu fonksiyonun class ın public ve public olmayan member larına erişim izni vardır. ) Standalone functions, entire classes or member functions of other classes may be declared to be friends of another class. ( Bir class ın friend leri şunlar olabilir : Bağımsız(standalone,tek başına) bir fonksiyon, Bir class ın tamamı, Bir class ın member fonksiyonlarından biri ) Using friend functions can enhance performance. (friend fonksiyonları kullanmak performansı arttırabilir.) This section presents a mechanical example of how a friend function works. Later in the book, friend functions are used to overload operators for use with class objects (Chapter 11) and to create iterator classes (Chapter 20, Custom Templatized Data Structures). (Bu section da bir friend fonksiyonun nasıl çalıştığını gösteren bir örnek göreceğiz. 11. Chapter da, friend fonksiyonlar kullanarak, class objectler ile operator overload etmeyi öğreneceğiz. Mesela classa + classb diyeceğiz,+ operatorünü overload edeceğiz burada. Chapter20 de ise friend fonksiyonların iterator class2lar create etmek için nasıl kullanıldığını öğreneceğiz. ) Objects of an iterator class can successively select items or perform an operation on items in a container class object. Objects of container classes can store items. Using friends is often appropriate when a member function cannot be used for certain operations, as we ll see in Chapter 11. (Bir iterator class ının object leri item ları ardışık olarak seçebilir, veya bir container class object indeki item larda bir operation gerçekleştirebilir. Container class larının object leri item lar store edebilir(item tutabilir,item depolayabilir.) Bir member function bazı operation ları gerçekleştiremiyorsa, friend kullanmak uygun olabilir, chapter11 de bunu göreceğiz. ) (Bir fonksiyonu, bir class ın friend i olarak declare etmek için, class daki function prototype ının başına friend keyword yazılır. Class A... friend int add() // add fonksiyonundan Class A nın private field larına erişilebilir. 27

... ClassTwo class ının tüm member fonksiyonlarının, classone class ının friend i olması için, classone class ının tanımında şöyle deriz. ClassOne friend class ClassTwo; ) Software Engineering Observation 10.7 Even though the prototypes for friend functions appear in the class definition, friends are not member functions. (friend fonksiyonlar için olan prototype lar class definition da gözükmesine (yazılmasına) rağmen, friend ler member fonksiyon lar değildir) Software Engineering Observation 10.8 Member access notions of private, protected and public are not relevant to friend declarations, so friend declarations can be placed anywhere in a class definition. (private, protected ve public gibi class ın member larının erişim seviyelerini belirten keyword ler friend declaration lar için mühim değildir, bu keyword ler friend declaration ları ilgilendirmez, friend düşünürken bu keyword leri hiç düşünmene gerek yok yani. Dolayısıyla friend declaration ları class ın definition ında herhangi bir yerde yazılabilir, hiç fark etmez. ) Good Programming Practice 10.1 Place all friendship declarations first inside the class definition s body and do not precede them with any access specifier. (Önce, class definition ın body sinde tüm friendship leri yazalım. Ve friendshiplerin önüne access specifier(public, private, protected) koymayalım sakın.) Friendship is granted, not taken i.e., for class B to be a friend of class A, class A must explicitly declare that class B is its friend. ( Arkadaşlık hakkı alınmaz, verilir. Herkes kendi member larına erişim yetkisine sahip olacak olan arkadaşı kendi söyler. B class ının, A class ının friend i olabilmesi için, class A explicit bir şekilde şunu demelidir: class B benim friend imdir. Böylece class A, member larına erişebilme hakkını, class B ye vermiştir. Şöyle düşün. A class ı kendi arkadaşlarını kendi ağzıyla söyler. Mesela B benim arkadaşımdır der. B benim private field larıma erişebilir der. Aşağıdaki gibi: ClassA... friend ClassB... 28

) Also, the friendship relation is neither symmetric nor transitive; i.e., if class A is a friend of class B, and class B is a friend of class C, you cannot infer that class B is a friend of class A (again, friendship is not symmetric), that class C is a friend of class B (also because friendship is not symmetric), or that class A is a friend of class C (friendship is not transitive). (friendship ilişkisi symmetric değildir, transitive değildir. Class A is a friend of class B : buradan Class B is a friend of class A çıkarımında bulunamayız.) Software Engineering Observation 10.9 Some people in the OOP community feel that friendship corrupts information hiding and weakens the value of the object-oriented design approach. We will provide several examples of responsible friendship use. (OOP camiasındaki bazı insanlar, friendship in information hiding i bozduğunu düşünürler, OOP design yaklaşımının değerini zayıflattığını,düşürdüğünü düşünürler. Ancak biz birçok güvenilir friendship kullanımı örnekleri göstereceğiz. ) Modifying a Class s private Data with a Friend Function(Bir class ın private bir data sını friend fonksiyon kullanarak modify etmek) ( Aşağıdaki örnekte, friend function setx(), Count class ının private data member ı olan x i set ediyor(modify ediyor). ) The friend declaration (line 9) appears first (by convention) in the class definition, even before public member functions are declared. Again, this friend declaration can appear anywhere in the class. (friend function class içinde ilk satırda declare edilmiştir,gelenekten ötürü böyle yapılmıştır. Tekrar hatırlatalım. Bu friend declaration ı class içinde herhangi bir yerde olabilir, yeri fark etmez.) // Friends can access private members of a class. #include <iostream> using namespace std; class Count friend void setx( Count &, int ); // friend declaration Friend function setx() önce class içinde declare ediliyor public: Count() : x( 0 ) // initialize x to 0 // empty body 29

void print() const cout << x << endl; private: int x; // data member ; void setx( Count &c, int val ) c.x = val; // allowed because setx is a friend of Count int main() Count counter; cout << "initially : "; counter.print(); setx( counter, 8 ); cout << "finally : "; counter.print(); Sonra, friend function setx() class ın dışında define ediliyor. // create Count object // set x using a friend function setx() fonksiyonu, Count class ının friend i olarak declare edilmiştir. Bu sayede, setx() fonksiyonu Count class ının private data larına erişebilir, modify edebilir. Output: counter.x after instantiation: 0 counter.x after call to setx friend function: 8 Function setx (lines 29 32) is a C-style, stand-alone function it isn t a member function of class Count. For this reason, when setx is invoked for object counter, line 41 passes counter as an argument to setx rather than using a handle (such as the name of the object) to call the function, as in counter.setx( 8 ); ( setx fonksiyonu C stilinde bir standalone fonksiyondur, yani herhangi bir class ın fonksiyonu falan değildir. Ayrıca setx fonksiyonu Count class ının member function ı değildir. Bu sebeple, counter isimli object setx fonksiyonua argument olarak verilir, setx() fonksiyonu counter object in member ı olmadığı için, counter.setx(8) şeklinde kullanım yanlış olur. ) If you remove the friend declaration in class definition, you ll receive error messages indicating that function setx cannot modify class Count s private data member x. 30

(class definition daki friend keyword ünü silersek, setx() fonksiyonunun Count class ının private data member ı olan x i modify edemeyeceğini söyleyen error lar alırız.) As we mentioned, It is a mechanical example of using the friend construct. It would normally be appropriate to define function setx as a member function of class Count. It would also normally be appropriate to separate the program of Fig. 10.13 into three files: 1. A header (e.g., Count.h) containing the Count class definition, which in turn contains the prototype of friend function setx 2. An implementation file (e.g., Count.cpp) containing the definitions of class Count s member functions and the definition of friend function setx 3. A test program with main. ( Buradaki setx fonksiyonunu, Count class ının member function ı da olabilirdi, bu uygun olurdu. Ayrıca bu yazdığımız programı 3 ayrı dosyaya bölmek de uygun olurdu: 1- setx() friend function ın declaration ını da içeren Count class ının definition ı 2- Count class ının member function larının ve setx fonksiyonunun implementation ları. 3- Main() fonksiyonunu içeren bir test programı. ) Overloaded friend Functions It s possible to specify overloaded functions as friends of a class. Each function intended to be a friend must be explicitly declared in the class definition as a friend of the class. (Overloaded fonksiyonları bir class ın friend leri olarak specify etmek(belirlemek) mümkündür. Class ın friend i olmasını istediğimiz herbir fonksiyonu, class ın definition ında explicitly declare etmemiz gerekir. ) 10.5 Using the this Pointer The parentheses are required because the dot operator has higher precedence than the * operator. this->somemethod() (*this).somemethod() *this in parantez içine alınması önemlidir, çünkü. operator, * operatar dan daha yüksek bir önceliğe sahiptir. Without the parentheses, the expression *this.x would be evaluated as if it were parenthesized as *( this.x ), which is a compilation error, because the dot operator cannot be used with a pointer. Parantezler olmazsa; *this.somemethod ; bu kod *(this.x) şeklinde evaluate edilir. Bu da compilation error a neden olur. Çünkü dot operator, pointer ile kullanılamaz. Common Programming Error 10.7 31

Attempting to use the member selection operator (.) with a pointer to an object is a compilation error the dot member selection operator may be used only with an lvalue such as an object s name, a reference to an object, or a dereferenced pointer to an object. (dot operator a member selection operator da denilir. Dot operator, pointer ile kullanılırsa compilation error olur. Dot operator, sadece lvalue ile kullanılabilir, mesela - bir object in ismi ile kullanılabilir, - bir object e reference ile kullanılabilir, - bir objecte dereferenced pointer ile kullanılabilir.) One interesting use of the this pointer is to prevent an object from being assigned to itself. As we ll see in Chapter 11, self-assignment can cause serious errors when the object contains pointers to dynamically allocated storage. (this pointer ının ilginç bir kullanımı ise şudur: bir object in kendine assign edilmesini önler. Chapter 11 de, dynamically allocated storage a pointer a sahip olan bir object in self-assignment yapılırsa ne kadar ciddi error lara sebep olduğunu göreceğiz.) Using the this Pointer to Enable Cascaded Function Calls Another use of the this pointer is to enable cascaded member-function calls that is, invoking multiple functions in the same statement. The program modifies class Time s set functions settime, sethour, setminute and setsecond such that each returns a reference to a Time object to enable cascaded member function calls. Notice in Fig. 10.16 that the last statement in the body of each of these member functions returns *this (lines 22, 33, 44 and 55) into a return type of Time &. (this pointer ının bir diğer kullanım amacı ise şudur: to enable cascaded member functions. Yani aynı statement içinde(aynı satırda) birden fazla fonksiyon çağırmak mümkün olur bu sayede. Şu gibi : // cascaded function calls t.sethour( 18 ).setminute( 30 ).setsecond( 22 ); ) // Time.h // Cascading member function calls. // Time class ının definition ı. // Time.cpp de tanımlanan member function lar. #ifndef TIME_H #define TIME_H class Time 32

public: Time( int = 0, int = 0, int = 0 ); // default constructor edilmezse, default constructor da // set functions (the Time & return types enable cascading) verilen default değerler kullanılır Time &settime( int, int, int ); // set hour, minute, second member data ları initialize etmek için. Time &sethour( int ); // set hour Time &setminute( int ); // set minute Time &setsecond( int ); // set second // get functions (normally declared const) int gethour() const; // return hour int getminute() const; // return minute int getsecond() const; // return second // print functions (normally declared const) void printuniversal() const; // print universal time void printstandard() const; // print standard time private: int hour; // 0-23 (24-hour clock format) int minute; // 0-59 ; #endif int second; // 0-59 Default constructor ı kırmızıya boyadım. Eğer Time constructor ının parametreleri explicitly specify // Time.cpp // Time class ının member-function ları define ediliyor bu kodda. #include <iostream> #include <iomanip> #include "Time.h" // Time class definition, include ediliyor. using namespace std; // private data ları initialize etmek için constructor function kullanılıyor. // constructor da settime fonksiyonu çağırılarak variable lar set ediliyor. // default values are 0. Class definition(time.h) da belirlemiştik bunu. Time::Time( int hr, int min, int sec ) settime( hr, min, sec ); // hour, minute, and second, set edilir. Time &Time::setTime( int h, int m, int s ) // note Time & return (object i modiy et ve return et.) 33

sethour( h ); setminute( m ); setsecond( s ); return *this; // enables cascading // hour, set edilir. Time &Time::setHour( int h ) // note Time & return (object i modiy et ve return et.) if ( h >= 0 && h < 24 ) hour = h; else throw invalid_argument( "hour must be 0-23" ); return *this; // enables cascading // minute, set edilir. Time &Time::setMinute( int m ) // note Time & return (object i modiy et ve return et.) if ( m >= 0 && m < 60 ) minute = m; else throw invalid_argument( "minute must be 0-59" ); return *this; // enables cascading // second set edilir. Time &Time::setSecond( int s ) // note Time & return (object i modiy et ve return et.) if ( s >= 0 && s < 60 ) second = s; else throw invalid_argument( "second must be 0-59" ); return *this; // enables cascading /*getter functions are below*/ int Time::getHour() const 34

return hour; int Time::getMinute() const return minute; int Time::getSecond() const return second; // Time class ının instance ını, universal-time format da print et : (HH:MM:SS) void Time::printUniversal() const cout << setfill( '0' ) << setw( 2 ) << hour << ":" << setw( 2 ) << minute << ":" << setw( 2 ) << second; // Time class ının instance ını, standard-time format da print et : (HH:MM:SS AM or PM) void Time::printStandard() const cout << ( ( hour == 0 hour == 12 )? 12 : hour % 12 ) << ":" << setfill( '0' ) << setw( 2 ) << minute << ":" << setw( 2 ) << second << ( hour < 12? " AM" : " PM" ); /* fig10_17.cpp(main function) ; Cascading member-function calls with the this pointer.(this pointer kullanılarak, member function lar cascaded bir şekilde çağırılabilir. Bu bizim test kodumuzdur, yani main() fonksiyonu içerir bu kod.) */ #include <iostream> #include "Time.h" // Time class definition using namespace std; int main() Time t; // Time object, create edilir. 35 t.sethour(18), then returns a reference to object t as the value of this function call. The remaining expression is then interpreted as ( t.sethour(18) deyince, t object ine reference return eder, geriye kalan statement şu gibi düşünülebilir: ) t.setminute( 30 ).setsecond( 22 ); The t.setminute( 30 ) call executes and returns a reference to the object t. The remaining expression is interpreted as

// cascaded function calls t.sethour( 18 ).setminute( 30 ).setsecond( 22 ); // time, universal format da print edilir. cout << "Universal time: "; t.printuniversal(); // time, standard format da print edilir. cout << "\nstandard time: "; t.printstandard(); cout << "\n\nnew standard time: "; // cascaded function calls t.settime( 20, 20, 20 ).printstandard(); cout << endl; Output: Universal time: 18:30:22 Standard time: 6:30:22 PM New standard time: 8:20:20 PM t.settime( 20, 20, 20 ).printstandard(); satırında da cascading kullanılır. Burada olduğu gibi önce settime() fonksiyonu sonra printstandard() fonksiyonu çağırılmalıdır. Çünkü printstandard() fonksiyonu t object ine reference return etmez. Dolayısıyla, önce printstandard sonra settime fonksiyonu çağırılırsa(aşağıdaki gibi): t. printstandard().settime( 20, 20, 20 ); compile error alırız. Chapter 11 presents several practical examples of using cascaded function calls. One such example uses multiple << operators with cout to output multiple values in a single statement. (Chapter 11 de birçok cascaded function call örnekleri göreceğiz. Mesela single bir statement da, cout ile birden fazla değer output etmek için, birden fazla << operatörü kullanacağız, bunun örneğini yapacağız. ) 10.6 static Class Members In certain cases, only one copy of a variable should be shared by all objects of a class. A static data member is used for these and other reasons. Such a variable represents classwide information (i.e., a property that is shared by all instances and is not specific to any one object of the class). (Bazen, bir variable ın sadece bir kopyası, bir class ın tüm object leri tarafından paylaşılabilir. Yani tüm object ler aynı ortak dataya erişirler,yani static data ya. Static data lar, object e özel değildir, class a özeldir. ) 36

Performance Tip 10.3 Use static data members to save storage when a single copy of the data for all objects of a class will suffice.(yerden tasarruf etmek için, tüm object ler için, ortak bir data kullanmak yeterli ise, static data kullanılmalıdır.) Scope and Initialization of static Data Members Although they may seem like global variables, a class s static data members have class scope. ( Bir class ın static data member ının scope u, class ın scope u ile aynıdır. ) Also, static members can be declared public, private or protected. ( static member lar public, private, protected access specifier ları ile declare edilebilir. ) A fundamental-type static data member is initialized by default to 0. ( static data member, default olarak 0 a initialize edilir. ) If you want a different initial value, a static data member can be initialized once. A static const data member of int or enum type can be initialized in its declaration in the class definition. (Eğer static data member ınızın farklı bir initial değere sahip olmasını isterseniz, static data member ı initialize edebilirsiniz. Ancak static data member, sadece bir defa initialize edilebilir. Static const bir data member(int veya enum type ındaki) class definition da declare edilirken initialize edilebilir. ) However, all other static data members must be defined at global namespace scope (i.e., outside the body of the class definition) and can be initialized only in those definitions again, the next version of the C++ standard will allow initialization where these variables are declared in the class definition. (Ancak diğer tüm static data member lar global namespace scope da(class definition ın body sinin dışında) define edilir(tanımlanır), ve sadece bu definition larda initialize edilebilirler. C++ ın bir sonraki sürümü, bu variable ların class definition da declare edildikleri yerlerde initialize edilmesine izin verecektir. Yani şu anki C++ versiyonunda, önce static data member declare edilir class içinde, sonra class definition body si dışında define ve 37

initialize edilmek zorundadır.ancak bir sonraki C++ sürümünde, static data member class definition da declare edilirken initialize edilmesi mümkün olacaktır. ) If a static data member is an object of a class that provides a default constructor, the static data member need not be initialized because its default constructor will be called. (Bir static data member, default constructor provide eden bir class ın object i ise, static data member ın initialize edilmesine gerek kalmaz, çünkü bu class ın default constructor ı çağırılacaktır. ClassA ClassA() // default constructor var. ClassB static ClassA objecta // B class ı, A class ının static bir object ini içeriyor. ) Accessing static Data Members A class s private and protected static members are normally accessed through the class s public member functions or friends. (Bir class ın private ve protected static member larına, bu class ın public member function ları ve friend leri erişebilir. ) A class s static members exist even when no objects of that class exist. To access a public static class member when no objects of the class exist, simply prefix the class name and the scope resolution operator (::) to the name of the data member. For example, if our preceding variable martiancount is public, it can be accessed with the expression 38

Martian::martianCount when there are no Martian objects. (Of course, using public data is discouraged.) ( Bir class dan hiçbir object create edilmemiş olsa bile, bu class ın static member ları hala hayattadır. Bir class dan hiçbir object create edilmemişse, class ın static member ına, classname :: staticmember şeklinde ulaşılabilir. Örneğin, Martian class ının, martiancount public static variable ı olsun. Tabi şu da var ki, public static variable kullanımını tavsiye etmiyoruz. ) To access a private or protected static class member when no objects of the class exist, provide a public static member function and call the function by prefixing its name with the class name and scope resolution operator. A static member function is a service of the class, not of a specific object of the class. ( Bir class dan hiçbir object create edilmemişken, private veya protected bir static class member a erişmek için, public static member function provide edin. Sonra bu fonksiyonu şöyle çağırın, classname :: publicfunction(). Bu fonksiyon static member data için bir getter fonksiyon olacak şekilde yazın. ClassA private static int count; ) public static int getcount() return count; Software Engineering Observation 10.10 A class s static data members and static member functions exist and can be used even if no objects of that class have been instantiated. ( Bir class dan hiçbir object create edilmemiş olsa bile, bu class ın static data member ları ve static member fonksiyonları hayattadır, kullanılabilir. ) Demonstrating static Data Members Aşağıdaki örnek program şunları içerir: - private static data member called count, 39

- public static member function called getcount. Notice that neither line 8 nor line 12 includes keyword static, yet both lines refer to static class members. (.h dosyasında static member lar declare edilirken, yani class definition da, static keyword kullanılmıştır. Ancak.h dosyasının client ları (yani.h dosyasını include edip kullanan dosyalar,.cpp dosyaları) nda bu static member lar define ve initialize edilirken static keyword ler kullanılmaz. ) When static is applied to an item at global namespace scope, that item becomes known only in that file. The static class members need to be available to any client code that uses the class, so we declare them static only in the.h file. ( global namespace scope da, bir item a static uygulandığında(yani static keyword bir variable ın veya member function ın önüne geldiğinde), bu item sadece bu dosya(file) da bilinir(become known). Static class member ları class ı kullanan tüm client kodlarında available olmalıdır, işte biz static member ları bu yüzden sadece.h dosyasında static olarak declare ederiz. Böylece static member lar sadece.h dosyasında bilinirler, bu sayede.h dosyasını kullanan tüm clientlar(.cpp) da da bu static member lar bilinirler. ) Data member count maintains a count of the number of objects of class Employee that have been instantiated. ( count variable ı(static variable) Employee class ından instantiate edilen object sayısını tutar. ) When objects of class Employee exist, member count can be referenced through any member function of an Employee object in Fig. 10.19, count is referenced by both line 22 in the constructor and line 32 in the destructor. (Employee class ından object ler create edilmişse eğer, bu object lerin member function ları aracılığıyla, count reference edilebilir. Örneğin, Employee.cpp dosyasında, hem 22.satırda hem de 32. Satırda, count reference edilmiştir. ) Common Programming Error 10.8 It s a compilation error to include keyword static in the definition of a static data member at global namespace scope. 40

(global namespace scope neydi? Mesela Employee class ı define edildi.h dosyasında. Sonra Employee class ının member ları Employee.cpp dosyasında define edildi. Global namespace scope da, bir class ın static data member ı define edilirken, static keyword ünü(kelimesini) eklemek compilation error'a neden olur. ) 41

Line 8 defines and initializes the data member count to zero at global namespace scope and lines 12 15 define static member function getcount.(8.satırda Employee class ının static member variable ı, hem define edilir, hem de 0 a initialize edilir. Bu işlem, global namespace scope da gerçekleştirilir fark ettiyseniz. 12.-15. Satırlar arasında ise, Employee class ının getcount() isimli static member function ı define edilir. Bu function da global namespace scope da initialize edilmiş,dikkat edin. ) Notice that neither line 8 nor line 12 includes keyword static, yet both lines refer to static class members.(8. Satırda da, 12.satırda da static keyword kullanılmadığına dikkat edelim. Halbuki her iki satırda da static class member larına refer edilmektedir.) Figure 10.20 uses static member function getcount to determine the number of Employee objects in memory at various points in the program. 42

The program calls Employee::getCount() before any Employee objects have been created (line 12), after two Employee objects have been created (line 23) and after those Employee objects have been destroyed (line 34). ( getcount static member fonksiyonu kullanılarak, program ın farklı noktalarında, o anki memory de bulunan Employee object sayısı belirlenir. Employee::getCount(), - hiçbir Employee object create edilmemişken çağırılır. - 2 tane Employee object create edildikten sonra çağırılır. - Create edilen bu 2 Employee object destroy edildikten sonra çağırılır. ) Lines 16 29 in main define a nested scope. Recall that local variables exist until the scope in which they re defined terminates. In this example, we create two Employee objects in lines 17 18 inside the nested scope. As each constructor executes, it increments class Employee s static data member count. These Employee objects are destroyed when the program reaches line 29. At that point, each object s destructor executes and decrements class Employee s static data member count. ( 16. ve 29. Satırlar arasında nested scope define edilmiştir. Bu kullanıma dikkat et. Böyle bir kullanımın da mümkün olduğunu bil. Hatırlayalım, local variable lar define edildikleri scope terminate edilene kadar yaşarlar. Bu örnekte, nested loop içinde, 17. Ve 18. Satırlarda, 2 tane Employee object create ettik. Herbir constructor execute etiğinde(çalıştığında), Employee class ının static data member ı olan count bir arttırılır. Program 29. Satıra geldiğinde(yani nested scope un sonuna geldiğinde), create edilmiş olan Employee object ler destroy edilirler, count birer azaltılır. ) 43

A member function should be declared static if it does not access non-static data members or non-static member functions of the class. Unlike non-static member functions, a static member function does not have a this pointer, because static data members and static member functions exist independently of any objects of a class. The this pointer must refer to a 44

specific object of the class, and when a static member function is called, there might not be any objects of its class in memory. (Bir class ın bir member function ı, eğer class ın nonstatic data member larına ve nonstatic member function larına erişmiyorsa, static olarak declare edilmelidir. Nonstatic member function ların aksine, bir static member function da this pointer ı olmaz,kullanılmaz, çünkü static data member lar ve static member function lar, bir class ın object inden bağımsız olarak yaşarlar. This pointer ı bir class ın specific bir object ine refer etmek zorundadır, static member function çağırıldığında ise, memory de bu class ın hiçbir object i de olmaması da muhtemel bir senaryodur. ) Common Programming Error 10.9 Using the this pointer in a static member function is a compilation error. (Bir class ın static member function ında, this pointer ını çağırmak compilation error a neden olur.) Common Programming Error 10.10 Declaring a static member function const is a compilation error. The const qualifier indicates that a function cannot modify the contents of the object in which it operates, but static member functions exist and operate independently of any objects of the class. (Bir class ın static member function ını const olarak declare etmek, compilation error a neden olur. Çünkü, const qualifier bir fonksiyonun, içerisinde çalıştığı object i modify edemeyeceğini gösterir, ama static member function lar class ın object inden bağımsız olarak yaşarlar, bağımsız olarak çalışırlar.) 10.7 Proxy Classes Two of the fundamental principles of good software engineering are separating interface from implementation, and hiding implementation details. We strive to achieve these goals by defining a class in a header and implementing its member functions in a separate implementation file. ( İyi bir software engineering in 2 temel ilkesi vardır: Interface ve implementation ı birbirinden ayırmak Implementation detaylarını gizlemek Bunu şöyle yaparız : -.h(header) dosyasında, class ı define etmek - Bu class ın member function larını, farklı bir.cpp dosyasında(implementation file) implement etmek. ) 45

As we pointed out in Chapter 9, however, headers do contain a portion of a class s implementation and hints about others. For example, a class s private members are listed in the class definition in a header, so these members are visible to clients, even though the clients may not access the private members. ( Daha önce Chapter 9 da bahsetmiştik, header lar bir class ın implementation ının bir kısmını içerir, bir kısmının implementation ı hakkında ise ipuçları verir. Örneğin,.h dosyasında(header dosyasında), class definition ında class ın private member ları listelenmiştir. Dolayısıyla client lar, private member lara erişemeseler bile, client lar bu member ları görür. ) Revealing a class s private data in this manner potentially exposes proprietary information to clients of the class. We now introduce the notion of a proxy class that allows you to hide even the private data of a class from clients of the class. ( Bir class ın private data larını bu şekilde açığa vurmak(reveal), class ın client larına özel bilgileri teşhir eder. Şimdi proxy class ları öğreneceğiz, bu yolla bir class ın private data larını bile class ın client larından(kullanıcılarından) saklayabiliriz.) Providing clients of your class with a proxy class that knows only the public interface to your class enables the clients to use your class s services without giving the clients access to your class s implementation details. ( Class ımızın client larına(kullanıcılarına), proxy class provide ettik diyelim. Proxy class, class ımızın sadece public interface lerini biliyordur. Bu sayede, class ımızın client ları class ımızın implementation detaylarını bilmeden class ımızın hizmetlerini kullanabilirler. ) Implementing a proxy class requires several steps, which we demonstrate in Figs. 10.21-10.24. First, we create the class definition for the class that contains the proprietary implementation we would like to hide. ( Proxy class implement etmek, birkaç adım gerektirir, Figure 10.21 den Figure 10.24 e kadar olan adımlarda gösterildiği gibi. İlk olarak, özel bilgilerin, gizlemek istediğimiz bilgilerin implementation ını içeren class define edilir.h dosyasında. ) 46

Our example class, called Implementation, is shown in Fig. 10.21. The proxy class Interface is shown in Figs. 10.22 10.23. The test program and sample output are shown in Fig. 10.24. (Örnek class, Implementation dır(figure 10.21), implementation.h dosyasını inceleyin. Proxy class ı Interface dir, interface.h(figure 10.22) ve interface.cpp(figure 10.23) dosyasını inceleyin. Test programı(main function) ve bu programın output u Figure 10.24 de gösterilmiştir, inceleyin. ) Class Implementation (Fig. 10.21) provides a single private data member called value (the data we would like to hide from the client), a constructor to initialize value and functions setvalue and getvalue. ( Implementation isimli class daki, value isimli private data member var, ve biz bu data member ı class ın client larından saklamak istiyoruz diyelim. Ayrıca bu class ın constructor ı value yü initialize ediyor. Bunun haricinde, bu class setvalue ve getvalue isimli 2 tane member fonksiyon içeriyor. ) 47

We define a proxy class called Interface (Fig. 10.22) with an identical public interface (except for the constructor and destructor names) to that of class Implementation. The proxy class s only private member is a pointer to an Implementation object. Using a pointer in this manner allows us to hide class Implementation s implementation details from the client. Notice that the only mentions in class Interface of the proprietary Implementation class are in the pointer declaration (line 17) and in line 6, a forward class declaration. ( Interface isimli bir proxy class tanımlıyoruz. Bu class ın public interface i Implementation class ının public interface ile aynıdır, constructor ve destructor isimleri hariç. Proxy class ının tek private member ı şudur : bir Implementation object e pointer. Bu şekilde bir pointer kullanarak, Implementation class ının implementation detaylarını client dan saklayabiliriz. Interface isimli proxy class ımıza bakalım, burada Implementation class ı ile ilgili, Implementation isimli proprietary(özel,şahsi) class ımıza pointer(17.satır) ve 6.satırdaki forward class declaration dan başka bir bilgi yoktur. ) When a class definition uses only a pointer or reference to an object of another class (as in this case), the class header for that other class (which would ordinarily reveal the private data of that class) is not required to be included with #include. ( Bir class definition ı(interface.h), eğer sadece başka bir class(implementation.h) ın object ine pointer veya reference kullanırsa, kullanılmak istenilen class ın header(implementation.h) ı #include ile include edilmek zorunda değildir. Bizim örneğimiz de böyledir. Interface class ında Implementation object ine pointer vardır. Implementation.h dosyasını include etsek, Implementation class ının proprietary bilgilerini teşhir etmiş oluruz. Dolayısıyla bu class ı include etmiyoruz. Bunun yerine forward declaration kullanarak Implementation isimli class ı 6. Satırda declare ediyoruz. ) This is because the compiler doesn t need to reserve space for an object of the class. The compiler does need to reserve space for the pointer or reference. The sizes of pointers and references are characteristics of the hardware platform on which the compiler runs, so the compiler already knows those sizes. You can simply declare that other class as a data type with a forward class declaration (line 6) before the type is used in the file. ( Bunun nedeni şudur: Compiler ın, bir class ın object i için space reserve etmesine(yer ayırmasına) gerek yoktur. Compiler ın pointer veya reference için space reserve etmesine(yer ayırmasına) gerek yoktur. Pointer ların ve reference ların size ları, compiler ın 48

çalıştığı hardware a bağlıdır, compiler bu size ları zaten bilir. Diğer class(implementation.h) ı 6.satırdaki forward class declaration ı yazarak bir data type gibi declare edebiliriz, sonra bu type ı file ımızda(interface.h) kullanabiliriz. ) The member-function implementation file for proxy class Interface (Fig. 10.23) is the only file that includes the header Implementation.h (line 5) containing class Implementation. ( Gizlemek istediğimiz class implementation ını içeren Implementation.h dosyasını include eden tek dosya şudur: proxy class Interface in member function larının implement edildiği Interface.cpp(Figure 10.23). ) The file Interface.cpp (Fig. 10.23) is provided to the client as a precompiled object code file along with the header Interface.h that includes the function prototypes of the services provided by the proxy class. Client a şunlar provide edilmiştir: - Precompiled object code file halinde Interface.cpp - Proxy class(interface) tarafından provide edilen hizmetlerin function prototype larını içeren, header - Interface.h-. 49

Because file Interface.cpp is made available to the client only as object code, the client is not able to see the interactions between the proxy class and the proprietary class (lines 9, 17, 23 and 29). ( Interface.cpp dosyası, client a sadece object code olarak verilir. Bu yüzden client, proxy class(interface) ve proprietary class arasındaki etkileşimleri göremez(9,17,23 ve 29, satırlardaki etkileşimleri göremez. ) The proxy class imposes an extra layer of function calls as the price to pay for hiding the private data of class Implementation. Given the speed of today s computers and the fact that many compilers can inline simple function calls automatically, the effect of these extra function calls on performance is often negligible. ( Proxy class(interface), Implementation class ının private data larını saklamak, gizlemek için extra bir layer koyar, bu da ödenecek bedel olarak düşünülebilir. Bugünün bilgisayarlarının hızlarını ve çoğu compiler ın basit function call ları otomatik olarak inline edebildiklerini düşünürsek, bu extra function call ların performance üzerindeki etkisi ihmal edilebilir, göz ardı edilebilir. ) 50

Bu class ın client ı, bu dosyayı sadece precompiled object code olarak alıyormuş, peki neden precompiled object code olarak alıyor? Bunu nereden biliyoruz? Client kodda include edilmediği için mi böyle oluyor? Figure 10.24 tests class Interface. Notice that only the header for Interface is included in the client code (line 4) there is no mention of the existence of a separate class called Implementation. Thus, the client never sees the private data of class Implementation, nor can the client code become dependent on the Implementation code. ( Figure 10.24 de Interface class ı test edilmiştir. Client kodunda(yani 10.24 deki bu kodda) sadece Interface class ının header ının include edildiğine dikkat edelim. Implementation class ının varlığında ise hiç bahsedilmemiş bu kodda. Dolayısıyla, Implementation class ının private data sını client asla görmez, ve client kodu Implementation class ının koduna bağımlı değildir. ) Software Engineering Observation 10.11 51

A proxy class insulates client code from implementation changes.(proxy class (Interface.h), client kodunu(bu örnekte main function) implementation değişikliklerinden ayırır, ayrı tutar. ) Here***************** 10.8 Wrap-Up This chapter introduced several advanced topics related to classes and data abstraction. You learned how to specify const objects and const member functions to prevent modifications to objects, thus enforcing the principle of least privilege. You also learned that, through composition, a class can have objects of other classes as members. We introduced the topic of friendship and demonstrated how to use friend functions. (Bu chapter da...) You learned that the this pointer is passed as an implicit argument to each of a class s non-static member functions, allowing the functions to access the correct object s data members and other non-static member functions. You also saw explicit use of the this 52