friend
(C++)
Bazı durumlarda, sınıfın üyesi olmayan işlevlere veya ayrı bir sınıftaki tüm üyelere üye düzeyinde erişim vermesi yararlıdır. Bu ücretsiz işlevler ve sınıflar, anahtar sözcükle friend
işaretlenmiş arkadaş olarak bilinir. Yalnızca sınıf uygulayıcısı, arkadaşlarının kim olduğunu bildirebilir. İşlev veya sınıf kendisini herhangi bir sınıfın arkadaşı olarak bildiremez. Sınıf tanımında friend
, sınıfınızın özel ve korumalı üyelerine erişim vermek için bir üye olmayan işlevin veya başka bir sınıfın anahtar sözcüğünü ve adını kullanın. Şablon tanımında tür parametresi olarak friend
bildirilebilir.
Sözdizimi
friend-declaration
:
friend
function-declaration
friend
function-definition
friend
elaborated-type-specifier
;
;
friend
simple-type-specifier
;
friend
typename-specifier
;
friend
Bildirim
Daha önce bildirilmemiş bir friend
işlev bildirirseniz, bu işlev kapsayan sınıf dışı kapsama aktarılır.
Bir friend
bildirimde bildirilen işlevler, anahtar sözcüğü kullanılarak extern
bildirilmiş gibi değerlendirilir. Daha fazla bilgi için bkz. extern
.
Genel kapsamlı işlevler prototiplerinden önce işlev olarak friend
bildirilse de, üye işlevler tam sınıf bildiriminin ortaya çıkmasından önce işlev olarak friend
bildirılamaz. Aşağıdaki kod, böyle bir bildirimin nasıl başarısız olduğunu gösterir:
class ForwardDeclared; // Class name is known.
class HasFriends
{
friend int ForwardDeclared::IsAFriend(); // C2039 error expected
};
Yukarıdaki örnek sınıf adını ForwardDeclared
kapsama girer, ancak tam bildirimi (özellikle işlevi IsAFriend
bildiren bölüm) bilinmez. friend
sınıfındaki HasFriends
bildirimi bir hata oluşturur.
C++11'de bir sınıf için iki tür arkadaş bildirimi vardır:
friend class F;
friend F;
İlk form, en içteki ad alanında bu ada göre mevcut bir sınıf bulunmadıysa yeni bir F sınıfını tanıtır. C++11: İkinci form yeni bir sınıf sunmaz; sınıf önceden bildirildiğinde kullanılabilir ve bir şablon türü parametresi veya typedef
olarak friend
bildirildiğinde kullanılmalıdır.
Başvuruda bulunan tür henüz bildirilmemiş olduğunda kullanın friend class F
:
namespace NS
{
class M
{
friend class F; // Introduces F but doesn't define it
};
}
Bildirilmemiş bir sınıf türüyle kullanırsanız friend
bir hata oluşur:
namespace NS
{
class M
{
friend F; // error C2433: 'NS::F': 'friend' not permitted on data declarations
};
}
Aşağıdaki örnekte, friend F
NS kapsamı dışında bildirilen sınıfına başvurur F
.
class F {};
namespace NS
{
class M
{
friend F; // OK
};
}
Şablon parametresini bir arkadaş olarak bildirmek için kullanın friend F
:
template <typename T>
class my_class
{
friend T;
//...
};
Bir typedef'i arkadaş olarak bildirmek için kullanın friend F
:
class Foo {};
typedef Foo F;
class G
{
friend F; // OK
friend class F // Error C2371 -- redefinition
};
Birbirlerinin arkadaşı olan iki sınıfı bildirmek için, ikinci sınıfın tamamı birinci sınıfın arkadaşı olarak belirtilmelidir. Bu kısıtlamanın nedeni, derleyicinin yalnızca ikinci sınıfın bildirildiği noktada tek tek arkadaş işlevlerini bildirmek için yeterli bilgiye sahip olmasıdır.
Dekont
İkinci sınıfın tamamının birinci sınıfın arkadaşı olması gerekse de, birinci sınıftaki hangi işlevlerin ikinci sınıfın arkadaşı olacağını seçebilirsiniz.
arkadaş işlevleri
friend
İşlev, bir sınıfın üyesi olmayan ancak sınıfın özel ve korumalı üyelerine erişimi olan bir işlevdir. Arkadaş işlevleri sınıf üyesi olarak kabul edilmez; bunlar, özel erişim ayrıcalıkları verilen normal dış işlevlerdir. Arkadaşlar sınıfın kapsamında değildir ve başka bir sınıfın üyesi olmadığı sürece üye seçimi işleçleri (ve ->) kullanılarak çağrılmaz. İşlev friend
, erişim veren sınıf tarafından bildirilir. Bildirim, friend
sınıf bildiriminde herhangi bir yere yerleştirilebilir. Erişim denetimi anahtar sözcüklerinden etkilenmez.
Aşağıdaki örnekte bir Point
sınıf ve bir friend işlevi gösterilmektedir. ChangePrivate
İşlev, friend
parametre olarak aldığı nesnenin özel veri üyesine Point
erişebilir.
// friend_functions.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class Point
{
friend void ChangePrivate( Point & );
public:
Point( void ) : m_i(0) {}
void PrintPrivate( void ){cout << m_i << endl; }
private:
int m_i;
};
void ChangePrivate ( Point &i ) { i.m_i++; }
int main()
{
Point sPoint;
sPoint.PrintPrivate();
ChangePrivate(sPoint);
sPoint.PrintPrivate();
// Output: 0
1
}
Sınıf üyeleri arkadaş olarak
Sınıf üyesi işlevleri diğer sınıflarda arkadaş olarak bildirilebilir. Aşağıdaki örneği inceleyin:
// classes_as_friends1.cpp
// compile with: /c
class B;
class A {
public:
int Func1( B& b );
private:
int Func2( B& b );
};
class B {
private:
int _b;
// A::Func1 is a friend function to class B
// so A::Func1 has access to all members of B
friend int A::Func1( B& );
};
int A::Func1( B& b ) { return b._b; } // OK
int A::Func2( B& b ) { return b._b; } // C2248
Yukarıdaki örnekte yalnızca işlevine A::Func1( B& )
sınıfına B
erişim verilirfriend
. Bu nedenle, özel üyeye _b
erişim sınıfında A
doğrudurFunc1
, ancak içinde Func2
değildir.
friend
Sınıf, üye işlevleri bir sınıfın işlevleri olan, yani üye işlevleri friend
diğer sınıfın özel ve korumalı üyelerine erişimi olan bir sınıftır. Sınıftaki B
bildirimin friend
şöyle olduğunu varsayalım:
friend class A;
Bu durumda, sınıfındaki A
tüm üye işlevlerine sınıfına B
erişim verilmiştirfriend
. Aşağıdaki kod bir sınıf örneğidir friend
:
// classes_as_friends2.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class YourClass {
friend class YourOtherClass; // Declare a friend class
public:
YourClass() : topSecret(0){}
void printMember() { cout << topSecret << endl; }
private:
int topSecret;
};
class YourOtherClass {
public:
void change( YourClass& yc, int x ){yc.topSecret = x;}
};
int main() {
YourClass yc1;
YourOtherClass yoc1;
yc1.printMember();
yoc1.change( yc1, 5 );
yc1.printMember();
}
Açıkça belirtilmediği sürece arkadaşlık karşılıklı değildir. Yukarıdaki örnekte, öğesinin YourClass
üye işlevleri özel üyelerine YourOtherClass
erişemiyor.
Yönetilen bir türün (C++/CLI'da) herhangi bir friend
işlevi, friend
sınıfı veya friend
arabirimi olamaz.
Arkadaşlık devralınmadığından, 'den YourOtherClass
türetilen sınıflar'ın özel üyelerine erişemez YourClass
. Arkadaşlık geçişli değildir, bu nedenle arkadaşı YourOtherClass
olan sınıflar 'ın özel üyelerine erişemez YourClass
.
Aşağıdaki şekilde dört sınıf bildirimi gösterilmektedir: Base
, Derived
, aFriend
ve anotherFriend
. Yalnızca sınıfın aFriend
özel üyelerine Base
(ve herhangi bir üyeye Base
devralınmış olabilir) doğrudan erişimi vardır.
Diyagramda anotherFriend sınıfının, arkadaş sınıfı aFriend olan sınıf tabanıyla arkadaş ilişkisi olmadığı gösterilmektedir. aFriend sınıfı Temel sınıf tarafından arkadaştır, ancak Türetilmiş sınıfı Base'den devralsa bile Türetilen sınıfıyla bir arkadaş ilişkisi yoktur. Bu, devralma işleminin türetilmiş sınıfın temel sınıfla aynı arkadaşlara sahip olduğu anlamına gelmez.
Satır içi friend
tanımlar
Arkadaş işlevleri sınıf bildirimleri içinde tanımlanabilir (işlev gövdesi verilir). Bu işlevler satır içi işlevlerdir. Üye satır içi işlevleri gibi, tüm sınıf üyeleri görüldükten hemen sonra, ancak sınıf kapsamı kapatıldıktan önce (sınıf bildiriminin sonunda) tanımlanmış gibi davranırlar. Sınıf bildirimleri içinde tanımlanan arkadaş işlevleri, kapsayan sınıfın kapsamındadır.
Ayrıca bkz.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin