Aracılığıyla paylaş


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 friendbildirilebilir.

Sözdizimi

friend-declaration:
friend function-declaration
friend function-definition
friendelaborated-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 IsAFriendbildiren 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 friendbildirildiğ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 Berişim verilirfriend. Bu nedenle, özel üyeye _b erişim sınıfında A doğrudurFunc1, ancak içinde Func2değ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 Beriş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 YourOtherClasseriş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, aFriendve 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.

A diagram that shows the derivation implications of a friend relationship.

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.

Anahtar Sözcükler