Friend Fonksiyonlar ve Nesne Pointerları
|ARKADAŞ (FRİEND) FONKSİYONLAR
Bir fonksiyonun üyesi olmadıgı bir sınıfa ait özel (private) üyelere erisim hakkı olması istenebilir. Bu durumda arkadas (friend) fonksiyonlardan yararlanmak söz konusu olacaktır. Arkadas fonksiyonlar, sınıfın üye fonksiyonları degildir. Ancak o sınıfa iliskin özel elemanlara erisim hakkı vardır. Örnegin bir arkadas fonksiyon, testSinif sınıfı için su sekilde tanımlanabilir:
class testSinif
{
özel üyeler…
public:
friend void arkadasFonk();
…
};
Burada prototipi verilen arkadasFonk() isimli fonksiyon, programın daha sonraki satırlarında tanımlanacaktır. Bu tanım içinde, public tanımından önce yer alan sınıfın özel üyelerine erisim hakkı vardır. Arkadas fonksiyonlar, farklı türdeki iki sınıfın karsılastırılmasında kullanılabilir. Bu fonksiyonlar, özellikle iki sınıfın aynı fonksiyonu paylasması amacıyla kullanılır. Arkadas fonksiyonların sınıfın özel (private) üyelerine erisim hakkı vardır!
Class testSinif
{
private:
Özel degiskenler…
public:
…
friend void arkadas();
…
};
void arkadas()
{
Özel degiskenler
}
Burada dikkat edilirse arkadas() fonksiyonu class’a ait bir fonksiyon değildir.Ancak class içerisinde friend olduğu belirtilerek class üyelerine erişim hakkı tanınmıştır.
#include <iostream> using namespace std; // Sınıf tanımlanıyor.. class testSinif { private: int a,b; public: // Arkadas fonksiyon tanımlanıyor.. friend int fark(testSinif ts); testSinif(); }; // Kurucu fonksiyon.. testSinif::testSinif() { a=10; b=20; } // Arkadas fonksiyon tanımlanıyor.. int fark(testSinif ts) { if (ts.a == ts.b) return 0; return 1; } main() { testSinif ts; if (fark(ts)) cout << "Iki deger esit degil.."; else cout << "Iki deger esit.."; cout << "\n"; }
Burada testSinif isimli bir arkadas fonksiyonu tanımlamaktadır. Bu fonksiyon testSinif sınıfının bir üye fonksiyonu degildir. Söz konusu arkadas fonksiyonu,testSinif sınıfının özel kullanıma açık; yani private olarak tanımlanmıs üyelerini kullanabilmektedir. Bu özel üyelerin içerdigi degerleri karsılastırarak, birbirlerine esit olup olmadıkları konusunda bir sonucun üretilmesine yardımcı olmaktadır.
NESNE Pointerları (Göstergeleri)
Gösterge(işaretçi , pointer) , bir degiskenin bellekteki adresini tutan bir degisken olarak düsünülür. Pointerlar , bir degisken için degil bir nesne için de belirleyebiliriz.Yani pointer değişkenin adresini gösteriyordu bizim için şimdiyse bir nesnenin adresini bir pointer ile tutabiliriz.
Bir nesneye, ona isaret eden bir gösterge yardımıyla da erisilebilir. Burada dikkat edilecek nokta, nesnelerin üyelerine yapılan basvuruların “->” isleci ile yapılmasıdır.
#include <iostream> using namespace std; // Nesne tanımlanıyor.. class dizi { int x; public: dizi(int n) { x=n; } int oku() { return x; } }; int main() { // Nesne dizisine baslangıç degerleri veriliyor.. dizi d[5] = {2,7,0,3,9}; int i; // Dizinin baslangıç adresi alınıyor.. dizi *p; p=d; // Gösterge birer artırılarak degerler // görüntüleniyor.... for (i=0;i<=4;i++) { cout << p->oku() << "\n"; p++; } return 0; }
Yukarıda bes adet sayısal degeri bir nesne dizisi içine yerlestirdikten sonra, bu nesne dizisine bir gösterge atamak ve bu gösterge yardımıyla dizinin tüm elemanlarını görüntülemek istiyoruz;
p->oku() yerine (*p).oku() da yazılabilir.
NESNELER İÇİN this POİNTER’I
Bu bölümde this göstergesini tanımlayacagız. Bir üye fonksiyon her çagrıldıgında, kendisini çagıran nesneye isaret eden bir göstergeye
otomatik olarak aktarılır. Bu göstergeye this anahtar kelimesi ile ulasabiliriz. Örnegin asagıda belirtilen nesne tanımını göz önüne alalım:
class testSinif
{
int a;
..
};
Bir üye fonksiyon a degiskenine bir baslangıç degeri atayabilir:
a=100;
Bu ifade aslında su sekildeki bir ifadenin kısa gösterimidir:
this -> a=100;
Aşağıdaki programda 350 ve 150 gibi degerleri nesne degiskenlerine atadıktan sonra, bunların toplamını hesaplayarak görüntüleyecegiz. Bunu yaparken this göstergesinden yararlanacagız.
#include <iostream> using namespace std; // Nesne tanımlanıyor.. class testSinif { int sayi1,sayi2; public: testSinif(int x,int y) { this ->sayi1=x; this ->sayi2=y; } // Toplama islemi.. int topla() { return this -> sayi1 + this ->sayi2; } void goruntule(); }; // Görüntüleme islemi.. void testSinif::goruntule() { int t; t=this->topla(); cout << "Toplam=" << t << "\n"; } int main() { testSinif ob(350,150); ob.goruntule(); return 0; }
#include <iostream> using namespace std; class test{ public: test(int =0); void ekrana_yaz() const; int y; private: int x; friend void afonk(test t); }; test::test(int a){ x=a; y=900; } void test::ekrana_yaz() const{ cout << this->x << endl; cout << (*this).x << endl; cout << x << endl; cout << &(*this).x << endl; cout << this << endl; } void afonk(test t) { t.x=9; cout << endl << t.x << endl; } int main(){ test nesne(12); nesne.ekrana_yaz(); //cout << nesne.x << endl; //Hata verir. cout << endl << nesne.y << endl; afonk(nesne); return 0; }
Nesnelerin Basvuru(Referans) Biçiminde Fonksiyonlara Geçirilmesi
Bir nesnenin bir fonksiyona nasıl geçirildigini biliyoruz. Böyle bir durumda, ilgili nesnenin bir kopyası olusturularak, bu kopyası fonksiyona aktarılıyordu. Bunun yerine, nesnenin bir kopyasını olusturmadan, bir referans biçiminde fonksiyona geçirilmesi söz konusu olabilir. Bu durumda, & isareti yardımıyla nesne bir basvuru olarak fonksiyona geçirilir.
Örneğin;
void fonksiyon (testsinif &nesne)
Aşağı taraftaki C++ programını göz önüne alalım. Bu programda, testSinif isimli nesneyi kare() fonksiyonuna bir basvuru ile geçirmek istiyoruz. Bu program çalıstırıldıgında, kare(testSinif &d) deyimi ile d basvurusu nesneye geçiriliyor.
#include <iostream> using namespace std; // Sınıf tanımlanıyor.. class testSinif { int sayi; public: testSinif(int n) { sayi=n; } int deger() { return sayi; } }; // Kare alma islemi.. int kare(testSinif & d){ return d.deger()*d.deger(); } int main() { // Karesi alınacak degerler.. testSinif a(9), b(11); cout << kare(a) << "\n"; cout << kare(b) << "\n"; return 0; }
Program çıktısı;
81
121
#include <iostream> using namespace std; // Sınıf tanımlanıyor.. class testSinif { int sayi; public: testSinif(int n) { sayi=n; } int deger() { return sayi; } }; int kare(testSinif d) { d=testSinif(d.deger()+1); return d.deger()*d.deger(); } int kare2 (testSinif &d) { d=testSinif(d.deger()+1); return d.deger()*d.deger(); } int main() { // Karesi alınacak degerler.. testSinif a(9), b(11); cout << kare(a) << "\n"; cout << kare(b) << "\n"; cout<<a.deger()<<endl; cout<<b.deger()<<endl; cout<<"*****************"<<endl; cout << kare2(a) << "\n"; cout << kare2(b) << "\n"; cout<<a.deger()<<endl; cout<<b.deger()<<endl; return 0; }
Program çıktısı;
100
144
9
11
*****************
100
144
10
12