top of page

C++ Dilinde this pointer .!!

  • Writer: Yusuf Hançar
    Yusuf Hançar
  • May 30, 2023
  • 4 min read

Bir önceki class yazısında ucundan değindiğimiz this pointer konusunu ele alacağız. C++ dilinde sınıf içerisindeki static olmayan(non-static) üye fonksiyonların gizli bir sınıf türünden parametresi olduğuna değinmiştik. this pointer anahtar sözcüğü de sadece sınıfın non-static üye elemanları(data members) için kullanılmaktadır. C++ dilinin kuralları gereği de this ifadesi PR(pure R value) value expression olarak kategorize edilmektedir. Değerini gösteren *this ifadesi ise L value expression olarak ele alınmaktadır.

Yani this işaretçisi(pointer) o anda işlem gören nesneye işaret etmektedir. Sınıfın non-static veri elemanları ve fonksiyonlarına erişim için kullanılmaktadır. Aşağıda this işaretçisinin ne işe yaradığı ve kullanımının gerekli olduğu durumları örneklendirerek anlamaya çalışalım :


class ThisClass {
public :
    void smart_code();
};

int glob_func()
{
    this; 
}
*****************************
AÇIKLAMA: global olan glob_func() fonksiyonu içerisindeki this çağrısı syntax error.
*****************************
class ThisClass { 
public : 
    void smart_code(); 
};

void ThisClass::smart_code() 
{ 
    this;       
                 
    *this        
}
*****************************
AÇIKLAMA: this çağrısı smart_code fonksiyonu hangi nesne için çağırılırsa o nesnenin adresidir. *this ilgili adresteki nesneye erişim için kullanımdır. 

!!java dilinde this adresi değil hangi nesne için çağırılırsa o nesnenin kendisini ifade eder.
*****************************
class ThisClass {
private : 
    int sc; 
    
public : 
    void smart_code(); 
};

void ThisClass::smart_code()  
{
    sc = 3;
    this->sc = 4;
    (*this).sc = 5;
    ThisClass::sc = 6;
}
*****************************
AÇIKLAMA: this pointer kullanılarak çağırılan nesneye erişim ve değer atama ile ilgili örnekler verilmektedir. 

*İlk atama işleminde veri elemanına direkt erişim söz konusudur.
*İkinci atamada ise -> operatoru ile yapılan sonraki atama da this işaretçisi kullanılarak veri elemanına erişim söz konusudur. 
*Sonraki ise this pointer işaret edilen nesnenin veri elemanına erişim için kullanılır. 
*Sonuncu da ise sınıf adı ile :: operatoru ile nitelenerek erişim söz konusudur. 
*****************************
class ThisClass { 
public : 
    void smart_code();
    void this_func(); 
};

void ThisClass::smart_code()  
{ 
    cout << "smart_code işlevi çağrısı." << endl; 
    cout << "this : " << this << endl;
    this_func();
}

void ThisClass::this_func()  
{ 
    cout << "this_func işlevi çağrısı." << endl;  
    cout << "this : " << this << endl; 
}

int main()
{
    ThisClass sc;
    cout << "&sc : " << &sc << endl;
    sc.smart_code();
}
*****************************
AÇIKLAMA: this nesnesi ile ThisClass sınıfından oluşturulan sc nesnesinin adresleri aynı olacaktır. Çünkü hangi nesne için çağırılırsa onun adresidir demiştik.
*****************************
class ThisClass { 
public : 
    void smart_code();
};

void th_func(ThisClass* th)
{
    cout << "global th_func() çağrısı. " << th << endl;
}

void ThisClass::smart_code()  
{ 
    cout << "smart_code() çağrısı." << this << endl;  
    th_func(this);
}

int main() 
{ 
    ThisClass sc; 
    cout << "&sc : " << &sc << endl; 
    sc.smart_code(); 
}
*****************************
AÇIKLAMA: smart_code() fonksiyonu içerisinde maindeki ThisClass sınıfı türünden oluşturulan sc nesnesi için yapılan çağrı bu nesnesin adresi ile global th_func() fonksiyonuna çağrı yapılmıştır. Bunun içinde adresini kullanmaktadır.
*****************************
class ThisClass { 
public : 
    void smart_code(); 
};

void th_func(ThisClass& th) 
{ 
    cout << "global th_func() çağrısı. " << th << endl; 
}

void ThisClass::smart_code()  
{ 
    cout << "smart_code() çağrısı." << this << endl;   
    th_func(*this); 
}

int main() 
{ 
    ThisClass sc; 
    cout << "&sc : " << &sc << endl; 
    sc.smart_code(); 
}
*****************************
AÇIKLAMA: üstteki pointer ile yapılan örneğin reference semantik ile kullanımıdır ve sık sık kullanım ihtiyacı duyulan bir durumdur.
*****************************

Bir non-static data member hangi nesne için çağırılmış ise o nesnenin adresini;

  1. Bir pointer değişkene geçecekse(global bir fonksiyonu bu adres ile çağıracak ise),

  2. Reference semantik ile global bir fonksiyona geçecek ise this pointer kullanmak zorundadır.

ThisClass* ptr_smart_code();
ThisClass& ref_smart_code();  
*****************************
AÇIKLAMA: Sınıfın non-static üye fonksiyonlarının sınıf türünden adres ya da referans döndürdükleri durumlarda da this kullanılmaktadır. Bu durumun kullanım nedeni de; çağırıldığı nesnenin adresi ya da nesnenin kendisini döndürmesidir.
*****************************    
// thisclass.h
class ThisClass {  
public :  
    ThisClass* ptr_smart_code();
    ThisClass& ref_smart_code();
};

*******************************************************************

// thisclass.cpp
ThisClass* ThisClass::ptr_smart_code()
{
    return this;            
}

ThisClass& ThisClass::ref_smart_code() 
{
    return *this;
}

int main()
{
    ThisClass sc;
    sc.ptr_smart_code();         
    sc.ref_smart_code();       
}
*****************************
AÇIKLAMA: ptr_smart_code() fonksiyonunun geri dönüş değeri; bu fonksiyona yapılan çağrı yapan nesnenin adresidir. 
* sc.ptr_smart_code(); ifadesi sc nesnesinin adresine eşittir. 
* sc.ref_smart_code(); ifadesi sc nesnesinin kendisine eşittir. Hem ref_smart_code fonksiyonuna çağrı yapılır hem de sc nesnesi elde edilir.
***************************** 
// thisclass.h
class ThisClass {  
public :  
    ThisClass& smart_code1();      
    ThisClass& smart_code2();
    ThisClass& smart_code3();
};

*******************************************************************

// thisclass.cpp
ThisClass& ThisClass::smart_code1()   
{ 
    return *this; 
}

ThisClass& ThisClass::smart_code2()   
{ 
    return *this; 
}

ThisClass& ThisClass::smart_code3()   
{ 
    return *this; 
}

int main() 
{ 
    ThisClass sc;

    sc.smart_code1().smart_code2().smart_code3();  
    
    return 0;    
}
*****************************
AÇIKLAMA: Tanımlanan üç fonksiyonda *this döndürüyor.
C# ve java gibi dillerde bu çağrılara fluent API denir.
***************************** 
int main()
{
    int val = 5;
    double dval = 2.7;
    bool bval = true;

    cout << val << dval << bval << endl;
}
*****************************
AÇIKLAMA: buradaki çağrılarda cout << çağrısının geçerli olmasının nedeni derleyici sınıfın bir üye fonksiyonuna çağrıya dönüştürmektedir. Yani operator overloading ile geçerli kılınmaktadır. Olmasaydı eğer cout.operator<<(val) şeklinde yazmak zorunda kalırdık. Sınıfın üye fonksiyon çağrısı *this döndürmektedir. *this cout nesnesinin kendisidir. 
***************************** 
class ThisClass {
public :
    void smart_code();
    void const_func()const;
};

ThisClass glob_val;

void ThisClass::smart_code()         
{ 
     *this = glob_val;         // legal
}

void ThisClass::const_func()const      
{ 
// *this const ve const nesneye atama yapılamayağı için syntax error.
     *this = glob_val;    
}
class ThisClass { 
public :
    ThisClass* f1();
    ThisClass& f2();
    ThisClass* f3()const;
    ThisClass& f4()const;
};

ThisClass* ThisClass::f1()   // bunun gizli parametresi de ThisClass*
{
    return this;             // ThisClass* ------------ ThisClass*
}

ThisClass& ThisClass::f2()   // bunun gizli parametresi de ThisClass* 
{ 
    return *this;   // ThisClass* ------------ ThisClass* 
}

ThisClass* ThisClass::f3()const  // bunun gizli parametresi de ThisClass* 
{ 
    return this;    // const ThisClass* ----- ThisClass*   // syntax error.
}

ThisClass& ThisClass::f4()const  // bunun gizli parametresi de ThisClass*  
{ 
    return *this;    // const ThisClass* ---- ThisClass*   // syntax error. 
}
class ThisClass { 
public : 
    const ThisClass* f1()const; 
    const ThisClass& f2()const;   
}; 

const ThisClass* ThisClass::f1()const          
{ 
    return this;               //legal 
}

const ThisClass& ThisClass::f2()const          
{ 
    return *this;               // legal 
}
class ThisClass { 
public : 
    void smart_code();  
};

ThisClass glob_val;

void ThisClass::smart_code()
{
    this = &glob_val;                              
}
*****************************
AÇIKLAMA: this kendisi her zaman const ve PR value olduğu için atama sentaks hatasıdır.
***************************** 
class ThisClass { 
public : 
    void smart_code1();  
    //void smart_code1(ThisClass* const this);

    void smart_code2()const;
    //void smart_code2(const ThisClass* const this); 
};
*****************************
AÇIKLAMA: 
*this pointer kendisi top level const. kendisini değiştiremeyiz.
*const üye fonksiyonlar için ise low level const ve gösterdiği nesneyi değiştiremeyiz.
***************************** 

 
 
 

Recent Posts

See All
C++ Dilinde [[nodiscard]] attribute

C++’ta [[attribute]] (öznitelik) mekanizması, kod hakkında ek bilgi sağlayarak derleyicinin uyarılar vermesine, belirli optimizasyonlar...

 
 
 
C++ Dilinde constinit

C++20'de tanıtılan önemli bir özellik `constinit`'dir; bu özellik, statik depolama süresine sahip değişkenlerin derleme zamanında...

 
 
 

Comments


bottom of page