Mengapa saya tidak bisa melakukan ini?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
c++
inheritance
amrhassan.dll
sumber
sumber
Jawaban:
Anda tidak dapat menginisialisasi
a
danb
masukB
karena mereka bukan anggotaB
. Mereka adalah anggotaA
, oleh karena itu hanyaA
dapat menginisialisasi mereka. Anda dapat membuatnya menjadi publik, lalu melakukan penugasanB
, tetapi itu bukan opsi yang disarankan karena akan merusak enkapsulasi. Sebagai gantinya, buat konstruktor inA
to allowB
(atau subclass apa pun dariA
) untuk menginisialisasinya:sumber
a
danb
diB::B()
karena mereka pribadi. Anda tidak dapat menginisialisasi mereka karena mereka bukan anggotaclass B
. Jika Anda menjadikannya publik atau dilindungi, Anda dapat menetapkannya di badanB::B()
.a
danb
..." dan mengubahnya menjadi "Anda tidak dapat menginisialisasi ..." tanpa memastikan sisa kalimat masuk akal. Posting telah diedit.Mengesampingkan fakta bahwa mereka
private
, karenaa
danb
merupakan anggotaA
, mereka dimaksudkan untuk diinisialisasi olehA
konstruktor, bukan oleh konstruktor kelas lain (diturunkan atau tidak).Mencoba:
sumber
Entah bagaimana, tidak ada yang mencantumkan cara paling sederhana:
Anda tidak dapat mengakses anggota dasar dalam daftar penginisialisasi, tetapi konstruktor itu sendiri, seperti metode anggota lainnya, dapat mengakses
public
danprotected
anggota kelas dasar.sumber
B
dialokasikan, kemudian akan ditugaskan di dalamB
konstruktor. Tetapi menurut saya kompiler juga masih bisa mengoptimalkan ini.class A
kita tidak bisa mengandalkana
danb
diinisialisasi. Penerapan apa punclass C : public A
, misalnya, mungkin lupa untuk memanggila=0;
dan membiarkannyaa
tidak dimulai.class A { int a = 0;};
), atau di konstruktor kelas dasar. Subclass masih bisa menginisialisasi ulang mereka di konstruktornya sesuai kebutuhan.Ini adalah contoh yang berfungsi jika Anda ingin menginisialisasi anggota data kelas Basis yang ada di objek kelas Derived, sedangkan Anda ingin mendorong antarmuka nilai ini melalui panggilan konstruktor kelas Derived.
sumber
Meskipun ini berguna dalam kasus yang jarang terjadi (jika bukan itu masalahnya, bahasa akan mengizinkannya secara langsung), lihat Basis dari idiom Anggota . Ini bukan solusi bebas kode, Anda harus menambahkan lapisan tambahan warisan, tetapi itu menyelesaikan pekerjaan. Untuk menghindari kode boilerplate, Anda dapat menggunakan implementasi boost
sumber
Kenapa kamu tidak bisa melakukannya? Karena bahasa tidak memungkinkan Anda untuk menginisialisasi daftar penginisialisasi kelas dasar 'anggota dalam kelas turunan'.
Bagaimana Anda bisa menyelesaikannya? Seperti ini:
sumber
Jika Anda tidak menentukan visibilitas untuk anggota kelas, defaultnya adalah "pribadi". Anda harus menjadikan anggota Anda pribadi atau dilindungi jika Anda ingin mengakses mereka di subkelas.
sumber
Kelas agregat, seperti A dalam contoh Anda (*), harus memiliki anggotanya publik, dan tidak memiliki konstruktor yang ditentukan pengguna. Mereka diinisialisasi dengan daftar penginisialisasi, misalnya
A a {0,0};
atau dalam kasus AndaB() : A({0,0}){}
. Anggota kelas agregat dasar tidak dapat diinisialisasi secara individual dalam konstruktor dari kelas turunan.(*) Tepatnya, seperti yang disebutkan dengan benar, asli
class A
bukanlah gabungan karena anggota pribadi non-statissumber