Aracılığıyla paylaş


Üye Erişim Denetimi (C++)

Erişim denetimleri, bir sınıfın public arabirimini uygulama ayrıntılarından ve protected yalnızca türetilmiş sınıflar tarafından kullanılmak üzere olan üyelerden private ayırmanızı sağlar. Erişim tanımlayıcısı, sonraki erişim tanımlayıcısı karşılaşılana kadar ondan sonra bildirilen tüm üyeler için geçerlidir.

class Point
{
public:
    Point( int, int ) // Declare public constructor.;
    Point();// Declare public default constructor.
    int &x( int ); // Declare public accessor.
    int &y( int ); // Declare public accessor.

private:                 // Declare private state variables.
    int _x;
    int _y;

protected:      // Declare protected function for derived classes only.
    Point ToWindowCoords();
};

Varsayılan erişim bir sınıfta ve public bir yapı veya birleşimdedirprivate. Bir sınıftaki erişim tanımlayıcıları herhangi bir sırada istediğiniz sayıda kullanılabilir. Sınıf türlerinin nesneleri için depolama ayırması uygulamaya bağlıdır. Ancak, derleyicilerin erişim tanımlayıcıları arasında ardışık olarak daha yüksek bellek adreslerine üye atamasını garanti etmesi gerekir.

Üye Erişim Denetimi

Erişim Türü Anlamı
private olarak private bildirilen sınıf üyeleri yalnızca sınıfın üye işlevleri ve arkadaşları (sınıflar veya işlevler) tarafından kullanılabilir.
protected olarak protected bildirilen sınıf üyeleri, sınıfın üye işlevleri ve arkadaşları (sınıflar veya işlevler) tarafından kullanılabilir. Ayrıca, sınıfından türetilen sınıflar tarafından kullanılabilir.
public olarak public bildirilen sınıf üyeleri herhangi bir işlev tarafından kullanılabilir.

Erişim denetimi, nesneleri kullanılmaları amaçlanmamış şekillerde kullanmanızı önlemeye yardımcı olur. Açık tür dönüştürmeleri (yayınlar) yaptığınızda bu koruma kaybolur.

Dekont

Erişim denetimi tüm adlar için aynı şekilde geçerlidir: üye işlevleri, üye verileri, iç içe geçmiş sınıflar ve numaralandırıcılar.

Türetilmiş Sınıflarda Erişim Denetimi

İki faktör, türetilmiş bir sınıfta temel sınıfın hangi üyelerinin erişilebilir olduğunu denetler; aynı faktörler türetilmiş sınıfta devralınan üyelere erişimi denetler:

  • Türetilmiş sınıfın erişim tanımlayıcısını kullanarak temel sınıfı bildirip bildirmediği public .

  • Üyeye erişimin temel sınıfta ne olduğu.

Aşağıdaki tabloda bu faktörler arasındaki etkileşim ve temel sınıf üye erişiminin nasıl belirleneceği gösterilmektedir.

Temel Sınıfta Üye Erişimi

private protected public
Türetme erişimiyle her zaman erişilemez private türetme kullanıyorsanız private türetilmiş sınıfta private türetme kullanıyorsanız private türetilmiş sınıfta
protected türetme kullanıyorsanız protected türetilmiş sınıfta protected türetme kullanıyorsanız protected türetilmiş sınıfta
protected türetme kullanıyorsanız public türetilmiş sınıfta public türetme kullanıyorsanız public türetilmiş sınıfta

Aşağıdaki örnekte erişim türetmesi gösterilmektedir:

// access_specifiers_for_base_classes.cpp
class BaseClass
{
public:
    int PublicFunc(); // Declare a public member.
protected:
    int ProtectedFunc(); // Declare a protected member.
private:
    int PrivateFunc(); // Declare a private member.
};

// Declare two classes derived from BaseClass.
class DerivedClass1 : public BaseClass
{
    void foo()
    {
        PublicFunc();
        ProtectedFunc();
        PrivateFunc(); // function is inaccessible
    }
};

class DerivedClass2 : private BaseClass
{
    void foo()
    {
        PublicFunc();
        ProtectedFunc();
        PrivateFunc(); // function is inaccessible
    }
};

int main()
{
    DerivedClass1 derived_class1;
    DerivedClass2 derived_class2;
    derived_class1.PublicFunc();
    derived_class2.PublicFunc(); // function is inaccessible
}

'de DerivedClass1üye işlevi PublicFunc bir public üyedir ve ProtectedFunc bir üyedir protected çünkü BaseClass bir temel sınıftır public . PrivateFuncBaseClass, private ve türetilmiş sınıflar için erişilemez.

içinde DerivedClass2ve ProtectedFunc işlevleri PublicFunc bir private temel sınıf olduğundan BaseClass üye olarak kabul edilirprivate. PrivateFunc Yine , için ve BaseClassprivate türetilmiş sınıflar için erişilemez.

Türetilmiş bir sınıfı temel sınıf erişim tanımlayıcısı olmadan bildirebilirsiniz. Böyle bir durumda türetilmiş sınıf bildirimi anahtar sözcüğünü kullanıyorsa türetme dikkate class alınırprivate. Türetilmiş sınıf bildirimi anahtar sözcüğünü kullanıyorsa türetme dikkate struct alınırpublic. Örneğin aşağıdaki kod:

class Derived : Base
...

eşdeğerdir:

class Derived : private Base
...

Benzer şekilde, aşağıdaki kod:

struct Derived : Base
...

eşdeğerdir:

struct Derived : public Base
...

Erişim sahibi private olarak bildirilen üyeler, bu işlevler veya sınıflar temel sınıfta bildirimi friend kullanılarak bildirilmediği sürece işlevler veya türetilmiş sınıflar tarafından erişilemez.

Bir union türün temel sınıfı olamaz.

Dekont

Bir private temel sınıf belirtirken, türetilmiş sınıfın private kullanıcılarının üye erişimini anlaması için anahtar sözcüğünü açıkça kullanmanız önerilir.

Erişim denetimi ve statik üyeler

olarak privatebir temel sınıf belirttiğinizde, yalnızca statik olmayan üyeleri etkiler. Genel statik üyeler türetilmiş sınıflarda da erişilebilir. Ancak, işaretçiler, başvurular veya nesneler kullanarak temel sınıfın üyelerine erişmek için yeniden erişim denetimi uygulayan bir dönüştürme gerekebilir. Aşağıdaki örneği inceleyin:

// access_control.cpp
class Base
{
public:
    int Print();             // Nonstatic member.
    static int CountOf();    // Static member.
};

// Derived1 declares Base as a private base class.
class Derived1 : private Base
{
};

// Derived2 declares Derived1 as a public base class.
class Derived2 : public Derived1
{
    int ShowCount();    // Nonstatic member.
};

// Define ShowCount function for Derived2.
int Derived2::ShowCount()
{
    // Call static member function CountOf explicitly.
    int cCount = ::Base::CountOf();     // OK.

    // Call static member function CountOf using pointer.
    cCount = this->CountOf();  // C2247: 'Base::CountOf'
                               // not accessible because
                               // 'Derived1' uses 'private'
                               // to inherit from 'Base'
    return cCount;
}

Önceki kodda; erişim denetimi, bir Derived2 işaretçisinden Base işaretçisine dönüşümü yasaklar. İşaretçi this örtük olarak türündedir Derived2 *. İşlevi CountOf seçmek için türüne thisBase *dönüştürülmelidir. için dolaylı bir temel sınıf olduğundan Base böyle bir private dönüştürmeye Derived2izin verilmez. Temel sınıf türüne private dönüştürme yalnızca hemen türetilen sınıflara yönelik işaretçiler için kabul edilebilir. Bu nedenle tür Derived1 * işaretçileri türüne Base *dönüştürülebilir.

İşlevi seçmek için CountOf işaretçi, başvuru veya nesne kullanmadan yapılan açık çağrı, dönüştürme olmadığını gösterir. Bu nedenle aramaya izin verilir.

türetilmiş bir sınıfın üyeleri ve arkadaşları, Tişaretçiyi T doğrudan temel sınıfına privateTdönüştürebilir.

Sanal işlevlere erişim

İşlevlere virtual uygulanan erişim denetimi, işlev çağrısını yapmak için kullanılan türe göre belirlenir. İşlev bildirimlerini geçersiz kılma, belirli bir türün erişim denetimini etkilemez. Örnek:

// access_to_virtual_functions.cpp
class VFuncBase
{
public:
    virtual int GetState() { return _state; }
protected:
    int _state;
};

class VFuncDerived : public VFuncBase
{
private:
    int GetState() { return _state; }
};

int main()
{
   VFuncDerived vfd;             // Object of derived type.
   VFuncBase *pvfb = &vfd;       // Pointer to base type.
   VFuncDerived *pvfd = &vfd;    // Pointer to derived type.
   int State;

   State = pvfb->GetState();     // GetState is public.
   State = pvfd->GetState();     // C2248 error expected; GetState is private;
}

Yukarıdaki örnekte, yazmak VFuncBase için bir işaretçi kullanarak sanal işlevi GetState çağırmak öğesini çağırır VFuncDerived::GetStateve GetState olarak publicdeğerlendirilir. Ancak, türünde VFuncDerived bir işaretçi kullanılarak çağrılmasıGetState, sınıfında VFuncDerivedbildirildiği private için GetState erişim denetimi ihlalidir.

Dikkat

GetState sanal işlevi, VFuncBase temel sınıfının işaretçisi kullanılarak çağrılabilir. Bu, çağrılan işlevin bu işlevin temel sınıf sürümü olduğu anlamına gelmez.

Birden çok devralma ile erişim denetimi

Sanal temel sınıflar içeren birden çok devralma kafeslerinde, belirli bir ada birden fazla yolla ulaşılabilir. Bu farklı yollarda farklı erişim denetimi uygulanabileceği için derleyici en çok erişimi sağlayan yolu seçer. Aşağıdaki şekilde bakın:

Diagram showing access along the paths of an inheritance graph.

Diyagramda şu devralma hiyerarşisi gösterilmektedir: VBase sınıfı temel sınıftır. Sınıf LeftPath, sanal private VBase kullanarak VBase'den devralır. sınıfı RightPath de VBase'den devralır ancak sanal public VBase kullanır. Son olarak, Türetilen sınıfı LeftPath ve RightPath sınıfından LeftPath, public RightPath kullanarak public devralır.

Devralma grafiğinin yollarına erişme

Şekilde VBase sınıfında bildirilen bir ada her zaman RightPath sınıfıyla ulaşılır. Doğru yol daha erişilebilir çünkü RightPath temel sınıf olarak public bildirirken VBaseLeftPath olarak privatebildirirVBase.

Ayrıca bkz.

C++ Dil Başvurusu