Apa perbedaan antara publik
, swasta
, dan dilindungi
inheritance dalam C++? Semua pertanyaan saya've ditemukan di JADI berurusan dengan kasus-kasus tertentu.
class A
{
public:
int x;
protected:
int y;
private:
int z;
};
class B : public A
{
// x is public
// y is protected
// z is not accessible from B
};
class C : protected A
{
// x is protected
// y is protected
// z is not accessible from C
};
class D : private A // 'private' is default for classes
{
// x is private
// y is private
// z is not accessible from D
};
CATATAN PENTING: Kelas B, C dan D semuanya mengandung variabel x, y dan z. Itu hanya pertanyaan tentang akses.
Tentang penggunaan dilindungi dan pribadi warisan yang bisa anda baca di sini.
Untuk menjawab pertanyaan itu, saya'd seperti untuk menggambarkan anggota's accesor pertama dalam kata-kata saya sendiri. Jika anda sudah mengetahui hal ini, melompat ke judul "berikutnya:".
Ada tiga orang asesor yang saya'm sadar: publik
, dilindungi
dan swasta
.
Mari:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
Base
juga menyadari bahwa Base
berisi publicMember
.Base
berisi protectedMember
.Base
menyadari privateMember
.Dengan "menyadari", maksud saya "mengakui keberadaan, dan dengan demikian dapat akses".
Hal yang sama terjadi dengan public, private dan protected warisan. Let's mempertimbangkan kelas Basis
dan Anak
yang mewarisi dari Base
.
public
, segala sesuatu yang menyadari Basis
dan Anak
ini juga menyadari bahwa Anak
mewarisi dari Base
.dilindungi
, hanya Anak
, dan anak-anak, mengetahui bahwa mereka mewarisi dari Base
.pribadi
, tidak ada yang lain dari Anak
adalah menyadari warisan.Membatasi visibilitas warisan akan membuat kode tidak dapat melihat bahwa beberapa kelas yang mewarisi kelas lain: konversi Implisit dari turunan ke dasar won't bekerja, dan static_cast
dari dasar ke yang berasal won't bekerja dengan baik.
Hanya anggota/teman-teman dari kelas dapat melihat pribadi, warisan, dan hanya anggota/teman-teman dan kelas turunan dapat melihat dilindungi warisan.
umum warisan
tombol kelas : publik jendela { };
dilindungi warisan
boost::compressed_pair
berasal dari kelas yang kosong dan menyimpan menggunakan memori kosong kelas dasar optimasi (contoh di bawah ini doesn't menggunakan template untuk tetap berada pada titik):struct empty_pair_impl : dilindungi empty_class_1 { non_empty_class_2 kedua; };
struct pasangan : pribadi empty_pair_impl { non_empty_class_2 &kedua() { kembali ini->kedua; }
empty_class_1 &pertama() { kembali ini; // perhatikan kita kembali ini! } };
* swasta** warisan
template
umum anggota
kelas sepasang { umum: Pertama pertama; Kedua kedua; };
kelas jendela { umum: int getWidth() const; };
dilindungi anggota
class stack {
protected:
vektor
kelas jendela { protected: batal registerClass(window_descriptor w); };
* swasta** anggota
kelas jendela { pribadi: int lebar; };
Perhatikan bahwa C-gaya gips sengaja memungkinkan pengecoran kelas yang diturunkan untuk dilindungi atau swasta kelas dasar dalam mendefinisikan dan cara yang aman dan dilemparkan ke arah lain juga. Ini harus dihindari di semua biaya, karena hal ini dapat membuat kode tergantung pada rincian pelaksanaan - tetapi jika diperlukan, anda dapat menggunakan teknik ini.
Itu harus dilakukan dengan cara yang umum anggota dari kelas dasar yang terkena dari class turunan.
Sebagai litb menunjukkan, publik warisan tradisional warisan yang anda'll melihat dalam kebanyakan bahasa pemrograman. Yang ini model yang "-" hubungan. Pribadi warisan, sesuatu AFAIK aneh untuk C++, adalah "DILAKSANAKAN DALAM HAL" hubungan. Yang ingin anda gunakan **** antarmuka publik di kelas yang diturunkan, tapi don't ingin pengguna dari kelas yang diturunkan untuk memiliki akses ke antarmuka. Banyak yang berpendapat bahwa dalam hal ini anda harus agregat kelas dasar, yang alih-alih memiliki dasar kelas sebagai basis pribadi, membuat anggota yang diturunkan dalam rangka untuk menggunakan kembali kelas dasar's fungsi.
Tiga kata kunci juga digunakan dalam konteks yang sama sekali berbeda untuk menentukan visibilitas warisan model.
Tabel ini mengumpulkan semua kemungkinan kombinasi dari komponen deklarasi dan warisan menghadirkan model yang dihasilkan akses ke komponen ketika subclass adalah benar-benar didefinisikan.
Tabel di atas ditafsirkan dengan cara sebagai berikut (lihat baris pertama):
jika sebuah komponen adalah menyatakan sebagai umum dan kelas warisan sebagai umum yang dihasilkan akses adalah umum.
Contoh:
class Super {
public: int p;
private: int q;
protected: int r;
};
class Sub : private Super {};
class Subsub : public Sub {};
Sehingga akses untuk variabel p
, q
, r
di kelas Subsub ini tidak ada.
contoh Lain:
class Super {
private: int x;
protected: int y;
public: int z;
};
class Sub : protected Super {};
Sehingga akses untuk variabel y
, z
di kelas Sub adalah dilindungi dan untuk variabel x
adalah tidak ada.
lebih rinci contoh:
class Super {
private:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
int main(void) {
Super object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
Sekarang mari kita mendefinisikan sebuah subclass:
class Sub : Super { };
int main(void) {
Sub object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
Kelas yang ditentukan bernama Sub yang merupakan subclass dari class bernama Super
atau Sub
kelas ini berasal dari Super
kelas.
The Sub
kelas tidak memperkenalkan variabel baru atau fungsi-fungsi baru. Apakah itu berarti bahwa setiap objek Sub
class mewarisi semua sifat-sifat setelah Super
kelas yang pada kenyataannya copy dari Super
kelas' benda-benda?
No. Itu tidak.
Jika kita mengkompilasi kode berikut, kita akan mendapatkan apa-apa tapi kesalahan kompilasi mengatakan bahwa masukan
dan get
metode ini adalah tidak dapat diakses. Mengapa?
Ketika kita menghilangkan visibilitas penspesifikasi, compiler mengasumsikan bahwa kita akan menerapkan apa yang disebut swasta warisan. Itu berarti bahwa semua umum superclass komponen berubah menjadi swasta akses pribadi superclass komponen won't dapat diakses sama sekali. Ini akibatnya berarti bahwa anda tidak diizinkan untuk menggunakan kedua dalam subclass.
Kita harus memberitahu compiler bahwa kita ingin melestarikan sebelumnya menggunakan kebijakan akses.
class Sub : public Super { };
Jangan disesatkan: itu tidak berarti bahwa komponen private Super class (seperti penyimpanan variabel) akan berubah menjadi masyarakat yang agak ajaib cara. Swasta komponen akan tetap swasta, semua akan tetap umum.
Benda-benda Sub
kelas dapat melakukan "hampir" hal yang sama seperti kakak-kakak mereka diciptakan dari Super
kelas. "Hampir" karena fakta menjadi sebuah subclass juga berarti bahwa kelas kehilangan akses ke swasta komponen dari superclass. Kita tidak bisa menulis fungsi anggota dari Sub
kelas yang akan mampu untuk secara langsung memanipulasi penyimpanan variabel.
Ini adalah sangat serius pembatasan. Apakah ada solusi?
Ya.
Ketiga tingkat akses ini disebut dilindungi. Kata kunci dilindungi berarti bahwa komponen yang ditandai dengan berperilaku seperti satu publik ketika digunakan oleh subclass dan terlihat seperti satu pribadi ke seluruh dunia. -- Ini benar hanya untuk publik mewarisi kelas (seperti kelas Super dalam contoh kita) --
class Super {
protected:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
class Sub : public Super {
public:
void print(void) {cout << "storage = " << storage;}
};
int main(void) {
Sub object;
object.put(100);
object.put(object.get() + 1);
object.print();
return 0;
}
Seperti yang anda lihat pada contoh kode kita baru fungsionalitas untuk Sub
kelas dan itu salah satu hal yang penting: mengakses penyimpanan variabel dari kelas Super.
Itu tidak akan mungkin jika variabel dideklarasikan sebagai private. Dalam fungsi utama ruang lingkup variabel tetap tersembunyi pula jadi jika anda menulis sesuatu seperti:
object.storage = 0;
Compiler akan memberitahukan kepada anda bahwa itu adalah sebuah kesalahan: 'int Super::bagasi' dilindungi
.
Akhirnya, lalu program akan menghasilkan output sebagai berikut:
storage = 101
Member in base class : Private Protected Public
Jenis warisan : Objek diwariskan sebagai:
Private : Inaccessible Private Private
Protected : Inaccessible Protected Protected
Public : Inaccessible Protected Public
1) Publik Warisan:
a. Pribadi anggota dari kelas Dasar tidak dapat diakses dalam class Turunan.
b. Melindungi anggota dari kelas Dasar tetap dilindungi dalam class Turunan.
c. Semua anggota dari kelas Dasar tetap umum di class Turunan.
Jadi, kelas-kelas lain dapat menggunakan semua anggota dari kelas Dasar yang Diperoleh melalui kelas objek.
2) Dilindungi Warisan:
a. Pribadi anggota dari kelas Dasar tidak dapat diakses dalam class Turunan.
b. Melindungi anggota dari kelas Dasar tetap dilindungi dalam class Turunan.
c. Semua anggota dari kelas Dasar juga menjadi dilindungi anggota kelas Turunan.
Jadi, kelas-kelas lain dapat't penggunaan umum anggota dari kelas Dasar yang Diperoleh melalui kelas objek, tetapi mereka tersedia untuk subclass dari Berasal.
3) Pribadi Warisan:
a. Pribadi anggota dari kelas Dasar tidak dapat diakses dalam class Turunan.
b. Dilindungi & umum anggota dari kelas Dasar menjadi pribadi anggota kelas Turunan.
Jadi, tidak ada anggota dari kelas Dasar dapat diakses oleh kelas-kelas lain melalui kelas Turunan objek karena mereka swasta di class Turunan. Jadi, bahkan subclass yang Berasal dari kelas dapat't mengaksesnya.
Publik warisan model IS-hubungan. Dengan
class B {};
class D : public B {};
setiap D
is a B
.
Pribadi, warisan model IS-DILAKSANAKAN-MENGGUNAKAN hubungan (atau apa pun yang's disebut). Dengan
class B {};
class D : private B {};
D
adalah not B
, tapi setiap D
menggunakan B
dalam pelaksanaannya. Pribadi warisan yang selalu dapat dihilangkan dengan menggunakan penahanan bukan:
class B {};
class D {
private:
B b_;
};
Ini D
, juga, dapat diimplementasikan dengan menggunakan B
, dalam hal ini menggunakan b_
. Penahanan adalah kurang ketat coupling antara jenis dari warisan, sehingga secara umum harus diutamakan. Kadang-kadang menggunakan penahanan bukan pribadi warisan yang tidak nyaman seperti pribadi warisan. Sering yang's a lame excuse untuk menjadi malas.
Saya don't pikir siapa pun yang tahu apa yang dilindungi
warisan model. Setidaknya aku ingin't melihat ada penjelasan yang meyakinkan namun.
Jika anda mewarisi publik dari kelas lain, semua orang tahu anda mewarisi dan anda dapat digunakan polymorphically oleh siapa saja melalui kelas dasar pointer.
Jika anda mewarisi protectedly hanya anak-anak kelas akan dapat menggunakan anda polymorphically.
Jika anda mewarisi pribadi hanya diri sendiri akan dapat mengeksekusi orang tua metode kelas.
Yang pada dasarnya melambangkan pengetahuan seluruh kelas tentang hubungan anda dengan orang tua kelas
Data yang dilindungi anggota dapat diakses oleh setiap kelas yang diturunkan dari kelas anda. Data pribadi anggota, bagaimanapun, tidak bisa. Let's mengatakan kami yang berikut ini:
class MyClass {
private:
int myPrivateMember; // lol
protected:
int myProtectedMember;
};
Dari dalam ekstensi untuk kelas ini, referensi ini.myPrivateMember
tidak't bekerja. Namun, ini.myProtectedMember
akan. Nilai tersebut masih dirumuskan, jadi jika kita memiliki sebuah instansiasi dari kelas ini disebut myObj
, kemudian myObj.myProtectedMember
tidak't bekerja, sehingga hal ini mirip dengan fungsi sebuah data pribadi anggota.
Accessors | Base Class | Derived Class | World
—————————————+————————————+———————————————+———————
public | y | y | y
—————————————+————————————+———————————————+———————
protected | y | y | n
—————————————+————————————+———————————————+———————
private | | |
or | y | n | n
no accessor | | |
y: accessible
n: not accessible
Berdasarkan ini contoh untuk java... saya pikir sebuah meja kecil bernilai seribu kata-kata :)
Ringkasan:
Ketika mewarisi, anda dapat (dalam beberapa bahasa) mengubah jenis perlindungan data anggota dalam arah tertentu, misalnya dari dilindungi untuk umum.
Pribadi anggota dari kelas dasar hanya dapat diakses oleh anggota dari kelas dasar .
Umum anggota dari kelas dasar dapat diakses oleh anggota kelas dasar, anggota kelas turunan serta anggota yang berada di luar kelas dasar dan kelas turunan.
Dilindungi anggota dari kelas dasar dapat diakses oleh anggota dari kelas dasar serta anggota kelas turunan.
* swasta**: dasar
dilindungi: base + berasal
umum: base + berasal + anggota lain
Saya menemukan jawaban yang mudah dan begitu pikir posting ini untuk referensi di masa mendatang saya juga.
Nya dari link http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
class Base
{
public:
int m_nPublic; // can be accessed by anybody
private:
int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected:
int m_nProtected; // can be accessed by Base member functions, or derived classes.
};
class Derived: public Base
{
public:
Derived()
{
// Derived's access to Base members is not influenced by the type of inheritance used,
// so the following is always true:
m_nPublic = 1; // allowed: can access public base members from derived class
m_nPrivate = 2; // not allowed: can not access private base members from derived class
m_nProtected = 3; // allowed: can access protected base members from derived class
}
};
int main()
{
Base cBase;
cBase.m_nPublic = 1; // allowed: can access public members from outside class
cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}
It's pada dasarnya akses perlindungan masyarakat dan melindungi anggota dari kelas dasar di kelas yang diturunkan. Dengan semua warisan, kelas turunan dapat melihat publik dan dilindungi anggota pangkalan. Dengan pribadi warisan, hal ini dapat't. Dengan dilindungi, turunan kelas dan setiap kelas yang diturunkan dari yang dapat melihat mereka.