C++ ta private değişkene referans ile erişim

cemalb

Üye
Katılım
9 Eki 2019
Mesajlar
126
Puanları
1
Yazılı bir kaynaktan C++ çalışırken bir örnek aklıma takıldı.

Mesela Time isminde bir class'ımız olsun:

class Time {
public:
Time(int = 0, int = 0, int = 0);
void setTime(int, int, int);
int getHour();
int& badSetHour(int); //hour değişkeni return edilir.(yani private değişkene dışarıdan erişim sağlanır)

private:
int hour;
int minute;
int second;
};



Örnekte main() içinde şöyle bir atama yapmış. Anlamı nedir ?

Time t; //t nesnesi oluşturuldu.
int& hourRef = t.badSetHour(20); //böyle bir atama ile private değişkene erişti. Ama ben anlamadım?


private bir değişkene normalde erişim sağlanamazken burada referans ile erişim sağlanmış. ama & işareti aklımı karıştırdı. normalde referans ile erişimlerde pointer işareti * kullanılmaz mıyıdı???
 
Verdiğiniz örnekte zaten değişkene direkt erişmiyor. Muhtemelen arada geri dönüş değeri olan bir setter fonksiyonu (badSetHour) yazılmış. (Geri dönüş değeri olduğu için literatürde setter fonksiyonu olarak isimlendirilmiyor olabilir, tam emin olamadım.)
 
öyle zaten. ben sadece & olayını anlamadım. neyi ifade ediyor.?
int& hourRef = t.badSetHour(20); burda adres değeri return edip hourRef'e atamış sanırım. ama hourRef bir pointer olması gerekmez miydi?
 
int& badSetHour(int);
fonksiyonunuz adres değeri değil, referans değeri return ediyor. O yüzden karıştırdınız sanırım. Adres değeri döndürüyor olsaydı pointer tanımlayıp, pointer üzerinden erişim sağlanabilirdi. (pointer ile reference farklı şeyler.)

int& hourRef = t.badSetHour(20);
zaten burada da fonksiyonun geri dönüş değeri "int& hourRef" ile tanımlanmış olan hourRef referansına atanmış.
 
Teşekkür ederim. Peki neden & kullanılmış ?
 
Çünkü C++'da referans tanımı "variable type &" şeklinde yapılıyor. Örneğin
Kod:
int i = 16;
int& r = i;
burada integer tipinde i değişkeni oluşturduk ve 16 değerini atadık, integer referans edecek r değişkenini oluşturduk ve i değerini referans edecek şekilde atadık. Burada r=10 yazıp, i değerini görüntülersek, i değerinin de 10 olduğunu görürüz.

Örnek program :
Kod:
#include <iostream>
 
using namespace std;
 
int main () {
    int i = 16;
    int& r = i;
    
    cout << "i : " << i << endl;
    cout << "r : " << r << endl;
    
    cout << "------" << endl;
    
    r = 10;
    
    cout << "i : " << i << endl;
    cout << "r : " << r << endl;

   
   return 0;
}
Çıktısı:
Kod:
i : 16
r : 16
------
i : 10
r : 10
 
anladım çok teşekkür ederim.. böyle bir tanımlama olduğunu bilmiyordum.
şu aynı şey o zaman doğru mudur?
int i=16;
int* r;
r = &i; //artık i'yi gösteriyor.
*r= 10; //artık i de 10 oldu.

yani
int& r = i; demek bu şekilde pointer tanımlamanın daha kısa yolu diyebilir miyiz?
 
Pointer ve Reference ikisi birbirinden farklı şeyler. Birisi birinin kısayolu demeyelim. Olaya daha hakim arkadaşlar da açıklama yapacaktır.
 
@fatal1693 birkaç şeyde ben ekleyeyim. Hatam olursa düzeltin. (Uzun zamandır C++ kullanmıyorum.)

1-)Referanslar sabittir. Pointer değil.

2-)Referanslar tanımlanmadan önce değer verilmelidir. Pointer aşağıdaki şekilde tanımlanabilir.

int *ptr ;
ptr= &deger;

Ama referans aşağıdaki şekilde tanımlanmaz:
int i = 16;
int& r ;
r=i;

3-) Referans "Null" olmaz. Pointer da kullanılır.
int *ptr= NULL; ------> Hata vermez.
int& r =NULL; ---------> Hata alırsınız.

4-) Referansta array kullanamazsınız. (Pointer de kullanabilirsiniz.)
5-) Referansa refarans veremezsiniz. ( Pointere, pointer atanır.)
6-) Referanstan adres alamazsınız. (Pointirdan alabilirsiniz.)
7-)Referanslar C dilinde yoktur. C++'dan sonra eklenmiştir.
8--) Referans kullanımında bazı derleyiciler hata vermektedir.

Aşağıdaki kodları da incelemenizi tavsiye ederim.

Kod:
#include <iostream>
#include <conio.h>

using namespace std;

int main () {
 
int deger = 101;
std::cout << &deger<<endl; // degerin adresini yazar
std::cout << deger<<endl; // degerin içeriğini yazar
std::cout << "----------------------"<<endl;

int *ptr= &deger;

std::cout << ptr<<endl; // degerin adresini yazar
std::cout << *ptr<<endl; // degerin içeriğini yazar
std::cout << "----------------------"<<endl;
std::cout << "*********************************************"<<endl;
std::cout << "*********************************************"<<endl;
std::cout << "*********************************************"<<endl;


//oluşturduğumuz pointer'a yeni bir değer atıyalım.
int deger2=105;
ptr=&deger2;
std::cout << &deger<<endl; // degerin adresini yazar
std::cout << deger<<endl; // degerin içeriğini yazar
std::cout << "----------------------"<<endl;

std::cout << &deger2<<endl; // degerin adresini yazar
std::cout << deger2<<endl; // degerin içeriğini yazar
std::cout << "----------------------"<<endl;

std::cout << ptr<<endl; // degerin adresini yazar
std::cout << *ptr<<endl; // degerin içeriğini yazar
std::cout << "----------------------"<<endl;
std::cout << "*********************************************"<<endl;
std::cout << "*********************************************"<<endl;
std::cout << "*********************************************"<<endl;

// şimdide referans kullanalım.
int i = 16;
int& r = i;
int k=12345;
int m=98765;
int f=24680;
 
cout << "i : " << i << endl;
cout << "r : " << r << endl;
std::cout << "----------------------"<<endl;

i=45;
cout << "i : " << i << endl;
cout << "r : " << r << endl;
std::cout << "----------------------"<<endl;
std::cout << "*********************************************"<<endl;
std::cout << "*********************************************"<<endl;
std::cout << "*********************************************"<<endl;

// şimdi refere edilmiş r değerini değişelim. Bu durumda hem r hemde i değeri aynı anda değişecektir
r=k;
cout << "i : " << i << endl;
cout << "r : " << r << endl;
cout << "k : " << k << endl;
cout << "m : " << m << endl;
std::cout << "----------------------"<<endl;
// şimdide refre edilmiş r değerinine başka bir değer atıyalım. Bu durumda hem r hemde i değeri aynı anda değişecektir.
r=m;
cout << "i : " << i << endl;
cout << "r : " << r << endl;
cout << "k : " << k << endl;
cout << "m : " << m << endl;
std::cout << "----------------------"<<endl;
std::cout << "*********************************************"<<endl;
std::cout << "*********************************************"<<endl;
std::cout << "*********************************************"<<endl;

// şimdide i değerinine başka bir değer atıyalım. Bu durumda hem r hemde i değeri aynı anda değişecektir.
i=f;
cout << "i : " << i << endl;
cout << "r : " << r << endl;
cout << "f : " << f << endl;
std::cout << "----------------------"<<endl;

// Referans değerleri sabittir. Pointer ise hareketlidir. Referanstan birini değiştirince diğer değerde değişmektedir.
   getch();
   return 0;
}

(Kodlar biraz karışık oldu. Anlamadığınız yer olursa tekrar bakarız.)
İyi çalışmalar.
 
İlk önce o kodu yazanın C++'yi yeterli kadar anladığı söylenemez. Eğer mümkünse başka bir kaynaktan C++ öğrenmenizi tavsiye ederim. Yabancı dilde başlangıç için Accelerated C++ diye bir kitap var.

& bir değişken için takma bir ismi ifade ediyor. Göstergeye benziyor.

Temel türler için int, short vs.. takma isim kullanmaya gerek yok.

Ama bir sınıfa ait örneği, giriş çıkış akımlarını bir işleve geçerken & takma isimlerden faydalanıyoruz. Örneğin kendi oluşturduğumuz Time nesnesini çıkış akımına takma isimle göndermezsek bir kopyasını oluşturur. Bu da ek bir maliyet demek.

C++'de bir sınıfı yazdırmak için geleneksel olarak ostream & çıkış akımından faydalanıyoruz. Bir de Time sınıfında, sınıfa ait özel değişkenlerin nasıl ilklendirildiğine dikkat edin. Böylece geçersiz Time nesnesi kalmamış oldu.
C++:
#include <iostream>
#include <sstream>

using namespace std;

class Time
{
public:
    Time(short hour, short minute, short second)
        : hour_ (hour), minute_(minute), second_(second)
    {}

    short getTime() const;

private:
    friend ostream & operator<< (ostream &, Time const &);
    short hour_, minute_, second_;
};

ostream & operator<< (ostream & os, Time const & time)
{
    os << time.hour_ << ':' << time.minute_ << ':' << time.second_;
    return os;
}

int main()
{
    Time time(15,30,12);
    cout << time;
}
 

Forum istatistikleri

Konular
129,867
Mesajlar
930,872
Kullanıcılar
452,732
Son üye
erencok

Yeni konular

Geri
Üst