Mengapa saya tidak bisa melakukan ini?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Mengapa saya tidak bisa melakukan ini?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Jawaban:
Anda tidak dapat menginisialisasi a
dan b
masuk B
karena mereka bukan anggota B
. Mereka adalah anggota A
, oleh karena itu hanya A
dapat menginisialisasi mereka. Anda dapat membuatnya menjadi publik, lalu melakukan penugasan B
, tetapi itu bukan opsi yang disarankan karena akan merusak enkapsulasi. Sebagai gantinya, buat konstruktor in A
to allow B
(atau subclass apa pun dariA
) untuk menginisialisasinya:
class A
{
protected:
A(int a, int b) : a(a), b(b) {} // Accessible to derived classes
// Change "protected" to "public" to allow others to instantiate A.
private:
int a, b; // Keep these variables private in A
};
class B : public A
{
public:
B() : A(0, 0) // Calls A's constructor, initializing a and b in A to 0.
{
}
};
a
dan b
di B::B()
karena mereka pribadi. Anda tidak dapat menginisialisasi mereka karena mereka bukan anggota class B
. Jika Anda menjadikannya publik atau dilindungi, Anda dapat menetapkannya di badan B::B()
.
a
dan b
..." dan mengubahnya menjadi "Anda tidak dapat menginisialisasi ..." tanpa memastikan sisa kalimat masuk akal. Posting telah diedit.
Mengesampingkan fakta bahwa mereka private
, karena a
dan b
merupakan anggota A
, mereka dimaksudkan untuk diinisialisasi oleh A
konstruktor, bukan oleh konstruktor kelas lain (diturunkan atau tidak).
Mencoba:
class A
{
int a, b;
protected: // or public:
A(int a, int b): a(a), b(b) {}
};
class B : public A
{
B() : A(0, 0) {}
};
Entah bagaimana, tidak ada yang mencantumkan cara paling sederhana:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
Anda tidak dapat mengakses anggota dasar dalam daftar penginisialisasi, tetapi konstruktor itu sendiri, seperti metode anggota lainnya, dapat mengakses public
dan protected
anggota kelas dasar.
B
dialokasikan, kemudian akan ditugaskan di dalam B
konstruktor. Tetapi menurut saya kompiler juga masih bisa mengoptimalkan ini.
class A
kita tidak bisa mengandalkan a
dan b
diinisialisasi. Penerapan apa pun class C : public A
, misalnya, mungkin lupa untuk memanggil a=0;
dan membiarkannya a
tidak dimulai.
class A { int a = 0;};
), atau di konstruktor kelas dasar. Subclass masih bisa menginisialisasi ulang mereka di konstruktornya sesuai kebutuhan.
# include<stdio.h>
# include<iostream>
# include<conio.h>
using namespace std;
class Base{
public:
Base(int i, float f, double d): i(i), f(f), d(d)
{
}
virtual void Show()=0;
protected:
int i;
float f;
double d;
};
class Derived: public Base{
public:
Derived(int i, float f, double d): Base( i, f, d)
{
}
void Show()
{
cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl;
}
};
int main(){
Base * b = new Derived(10, 1.2, 3.89);
b->Show();
return 0;
}
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.
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
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:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
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.
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 Anda B() : 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-statis