Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Kelas dapat dideklarasikan dalam cakupan kelas lain. Kelas seperti itu disebut "kelas berlapis." Kelas berlapis dianggap berada dalam cakupan kelas penutup dan tersedia untuk digunakan dalam cakupan tersebut. Untuk merujuk ke kelas berlapis dari cakupan selain cakupan penutup langsungnya, Anda harus menggunakan nama yang sepenuhnya memenuhi syarat.
Contoh berikut menunjukkan cara mendeklarasikan kelas berlapis:
// nested_class_declarations.cpp
class BufferedIO
{
public:
enum IOError { None, Access, General };
// Declare nested class BufferedInput.
class BufferedInput
{
public:
int read();
int good()
{
return _inputerror == None;
}
private:
IOError _inputerror;
};
// Declare nested class BufferedOutput.
class BufferedOutput
{
// Member list
};
};
int main()
{
}
BufferedIO::BufferedInput dan BufferedIO::BufferedOutput dinyatakan dalam BufferedIO. Nama kelas ini tidak terlihat di luar cakupan kelas BufferedIO. Namun, objek jenis BufferedIO tidak berisi objek jenis BufferedInput atau BufferedOutput.
Kelas berlapis dapat langsung menggunakan nama, nama jenis, nama anggota statis, dan enumerator hanya dari kelas penutup. Untuk menggunakan nama anggota kelas lain, Anda harus menggunakan penunjuk, referensi, atau nama objek.
Dalam contoh sebelumnyaBufferedIO, enumerasi IOError dapat diakses langsung oleh fungsi anggota di kelas berlapis, atau BufferedIO::BufferedInput, BufferedIO::BufferedOutput seperti yang ditunjukkan dalam fungsi good.
Catatan
Kelas berlapis hanya mendeklarasikan jenis dalam cakupan kelas. Mereka tidak menyebabkan objek yang terkandung dari kelas berlapis dibuat. Contoh sebelumnya mendeklarasikan dua kelas berlapis tetapi tidak mendeklarasikan objek apa pun dari jenis kelas ini.
Pengecualian untuk visibilitas cakupan deklarasi kelas berlapis adalah ketika nama jenis dideklarasikan bersama dengan deklarasi maju. Dalam hal ini, nama kelas yang dideklarasikan oleh deklarasi ke depan terlihat di luar kelas penutup, dengan cakupannya didefinisikan sebagai cakupan non-kelas penutup terkecil. Contohnya:
// nested_class_declarations_2.cpp
class C
{
public:
typedef class U u_t; // class U visible outside class C scope
typedef class V {} v_t; // class V not visible outside class C
};
int main()
{
// okay, forward declaration used above so file scope is used
U* pu;
// error, type name only exists in class C scope
u_t* pu2; // C2065
// error, class defined above so class C scope
V* pv; // C2065
// okay, fully qualified name
C::V* pv2;
}
Akses hak istimewa di kelas berlapis
Menumpuk kelas dalam kelas lain tidak memberikan hak istimewa akses khusus ke fungsi anggota kelas berlapis. Demikian pula, fungsi anggota kelas tertutup tidak memiliki akses khusus ke anggota kelas berlapis.
Fungsi anggota di kelas berlapis
Fungsi anggota yang dideklarasikan dalam kelas berlapis dapat ditentukan dalam cakupan file. Contoh sebelumnya dapat ditulis:
// member_functions_in_nested_classes.cpp
class BufferedIO
{
public:
enum IOError { None, Access, General };
class BufferedInput
{
public:
int read(); // Declare but do not define member
int good(); // functions read and good.
private:
IOError _inputerror;
};
class BufferedOutput
{
// Member list.
};
};
// Define member functions read and good in
// file scope.
int BufferedIO::BufferedInput::read()
{
return(1);
}
int BufferedIO::BufferedInput::good()
{
return _inputerror == None;
}
int main()
{
}
Dalam contoh sebelumnya, sintaks nama jenis yang memenuhi syarat digunakan untuk mendeklarasikan nama fungsi. Deklarasi:
BufferedIO::BufferedInput::read()
berarti " read fungsi yang merupakan anggota BufferedInput kelas yang berada dalam cakupan BufferedIO kelas." Karena deklarasi ini menggunakan sintaks nama jenis yang memenuhi syarat, konstruksi formulir berikut dimungkinkan:
typedef BufferedIO::BufferedInput BIO_INPUT;
int BIO_INPUT::read()
Deklarasi sebelumnya setara dengan yang sebelumnya, tetapi menggunakan typedef nama sebagai pengganti nama kelas.
Fungsi Teman di kelas berlapis
Fungsi Teman yang dideklarasikan dalam kelas berlapis dianggap berada dalam cakupan kelas berlapis, bukan kelas penutup. Oleh karena itu, fungsi teman tidak mendapatkan hak istimewa akses khusus untuk anggota atau fungsi anggota kelas tertutup. Jika Anda ingin menggunakan nama yang dideklarasikan dalam kelas berlapis dalam fungsi teman dan fungsi teman didefinisikan dalam cakupan file, gunakan nama jenis yang memenuhi syarat sebagai berikut:
// friend_functions_and_nested_classes.cpp
#include <string.h>
enum
{
sizeOfMessage = 255
};
char *rgszMessage[sizeOfMessage];
class BufferedIO
{
public:
class BufferedInput
{
public:
friend int GetExtendedErrorStatus();
static char *message;
static int messageSize;
int iMsgNo;
};
};
char *BufferedIO::BufferedInput::message;
int BufferedIO::BufferedInput::messageSize;
int GetExtendedErrorStatus()
{
int iMsgNo = 1; // assign arbitrary value as message number
strcpy_s( BufferedIO::BufferedInput::message,
BufferedIO::BufferedInput::messageSize,
rgszMessage[iMsgNo] );
return iMsgNo;
}
int main()
{
}
Kode berikut menunjukkan fungsi GetExtendedErrorStatus yang dideklarasikan sebagai fungsi teman. Dalam fungsi , yang didefinisikan dalam cakupan file, pesan disalin dari array statis ke anggota kelas. Perhatikan bahwa implementasi GetExtendedErrorStatus yang lebih baik adalah mendeklarasikannya sebagai:
int GetExtendedErrorStatus( char *message )
Dengan antarmuka sebelumnya, beberapa kelas dapat menggunakan layanan fungsi ini dengan melewati lokasi memori tempat mereka ingin pesan kesalahan disalin.