C++ Dilinde Friend Declaration ve Attorney Client İlişkisi
- Yusuf Hançar
- Nov 9, 2023
- 3 min read
C++ dilinde önceki yazılarımızda access specifiers, ne oldukları ne amaçla kullanıldıkları ve buralara client kodların erişim senaryolarına değinmiştik. friend declaration ile sınıfın private erişim belirtecinde bulunan değişkenleri, işlevleri kullanabilme kabiliyeti kazandırılır. friend declaration ile sınıflar arasındaki coupling artar. Bu sadece sınıfın kendi kodlarında kullanılabilmektedir. Değişme özelliği yoktur yani bir sınıf diğerine bu arkadaşlığı sundu ise diğeri de sunan sınıfa arkadaşlık vermiş demek anlamına gelmez.!!!!
A friend of your friend is not your friend...
En yaygın olarak global fonksiyonlara verilir. Dediğimiz gibi bir sınıf diğer sınıflara verebilir. Nadiren de olsa sınıfların üye fonksiyonlarına da verilebilmektedir. friendship durumunda tüm private açık hale gelir, kısıtlı erişim söz konusu değildir(burada yazımıza attığımız başlık istisna olacak)
class SmartCode {
public :
SmartCode() = default;
private :
int val;
};
int main()
{
SmartCode sc;
sc.val;
}
*****************************
AÇIKLAMA: error: ‘int SmartCode::val’ is private within this context
*****************************
CEVAP: syntax error
*****************************
#include <iostream>
using namespace std;
class SmartCode {
private:
void private_func(int val)
{
cout << "SmartCode::private_func() called." << endl;
}
public:
friend void gl_func(int);
};
void gl_func(int val)
{
SmartCode sc;
sc.private_func(val);
}
int main()
{
gl_func(10);
return 0;
}
*****************************
AÇIKLAMA: global foo fonksiyonu SmartCode sınıfının private üyelerine erişebilir.
*****************************
CEVAP :
*****************************
ATTORNEY-CLIENT ve FRIENDSHIP
Private öğelerine erişmek istediğimiz sınıfa doğrudan arkadaşlık vermek yerine kendi oluşturacağımız bir yardımcı sınıfa arkadaşlık vereceğiz.
Yardımcı Helper sınıfımız yalnızca static private işlevlere sahip olacak ve o da öğelerine erişeceğimiz sınıfa arkadaşlık verecektir.
#include <iostream>
using namespace std;
class Client {
private:
int mx1, mx2;
void pfunc1()
{
cout << "pfunc1 called" << endl;
}
public:
void pfunc2()
{
cout << "pfunc2 called" << endl;
}
void pfunc3()
{
cout << "pfunc3 called" << endl;
}
friend class Attorney;
};
class Attorney {
private:
static void pfunc(Client& cl)
{
cl.pfunc1();
}
static int get_mx(const Client& cl)
{
return cl.mx1;
}
friend class OtherClass;
};
class OtherClass {
public:
void foo(Client& cl)
{
Attorney::pfunc(cl);
auto val{ Attorney::get_mx(cl) };
cout << "mx1 : " << val << endl;
}
};
int main()
{
Client cl;
OtherClass oth;
// Artık pfunc2 çağrılabilir, çünkü public olarak tanımlandı.
cl.pfunc2();
// Bu satır hata verecektir, çünkü pfunc1() hala özeldir.
// cl.pfunc1();
// Attorney sınıfı üzerinden pfunc1() fonksiyonunu çağırır.
oth.foo(cl);
return 0;
}
*****************************
AÇIKLAMA:
*****************************
CEVAP :
*****************************
İç içe sınıflar (Nested) ile arkadaş(Friend) sınıflar birbirinden farklı yapılardır ve karıştırılmamalıdır.
Nested class kullanımında bir sınıfın içindeki sınıf ona bağlı, kendi başına bir sınıf değildşr.
Friend sınıflar ise kendi başına özellikleri olan ayrı ayrı sınıflardır.
Global fonksiyon ile private data memberlara erişemeyiz. Friend fonksiyon kullanarak, global fonksiyonları snıfımıza friend olarak tanıtıp, private datalara erişebiliriz.
Nesneye Dayalı Programlamada (OOP), friend kullanımı çok iyi bir yöntem değildir.
Genelde operatör overload ederken kullanılır, başka yerlerde kullanılmaz.
#include <iostream>
using namespace std;
class SmartCode {
public:
SmartCode(int value) : data(value) {}
// << operator overloading
friend ostream& operator<<(ostream& out, const SmartCode& obj)
{
out << obj.data;
return out;
}
private:
int data;
};
int main()
{
SmartCode obj(42);
std::cout << obj << std::endl;
return 0;
}
*****************************
AÇIKLAMA: friend kullanılarak << operatoru SmartCode sınıfı için overload edilmiş ve bu sınıftan oluşturulan nesne çıkış akımına << operator ile verilebilmiştir.
*****************************
CEVAP :
*****************************
#include <iostream>
using namespace std;
class Date {
int mo, da, yr;
public:
Date(int m, int d, int y)
{
mo = m; da = d; yr = y;
}
friend ostream& operator<<(ostream& os, const Date& dt);
friend istream& operator>>(istream& is, Date& dt);
};
ostream& operator<<(ostream& os, const Date& dt)
{
os << dt.mo << '/' << dt.da << '/' << dt.yr;
return os;
}
istream& operator>>(istream& is, Date& dt)
{
is >> dt.mo >> dt.da >> dt.yr;
return is;
}
int main()
{
Date dt(29, 5, 1994);
cout << dt;
}
*****************************
AÇIKLAMA:
*****************************
CEVAP :
*****************************

ความคิดเห็น