Bunu neden yapamıyorum?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Bunu neden yapamıyorum?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Yanıtlar:
Sen başlatılamıyor a
ve b
içinde B
onlar üyesi olmayan çünkü B
. Üyesidirler A
, bu nedenle yalnızca A
onları başlatabilirler. Bunları herkese açık hale getirebilir, sonra içinde atama yapabilirsiniz B
, ancak bu, kapsüllemeyi yok edeceği için önerilen bir seçenek değildir. Bunun yerine, onları başlatmaya (veya herhangi bir alt sınıfına ) A
izin vermek için bir yapıcı oluşturun :B
A
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
ve b
de B::B()
onlar özeldir çünkü. Üyeleri olmadıkları için onları başlatamazsınız class B
. Bunları halka açık hale getirdiyseniz veya koruyorsanız, bunları bünyesinde atayabilirsinizB::B()
.
a
ve b
..." yazdım ve cümlenin geri kalanının mantıklı olduğundan emin olmadan "İlklendiremezsin ..." olarak değiştirdim. Gönderi düzenlendi.
Kenara bunlar aslında bırakılması private
için, a
ve b
bir üyesi olan A
bunlar tarafından başlatılması için amaçlanmıştır, A
bireyin yapıcılar, başka bir sınıfın yapıcılar tarafından (türetilmiş ya da değil) olup.
Deneyin:
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) {}
};
Her nasılsa, hiç kimse en basit yolu listelemedi:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
Başlatıcı listesindeki temel üyelere erişemezsiniz, ancak kurucunun kendisi, diğer herhangi bir üye yöntemi gibi, temel sınıfın public
ve protected
üyelerine erişebilir .
B
tahsis edildiğinde ilk önce varsayılan olarak başlatılacak , ardından B
's yapıcısının içine atanacaktır . Ancak derleyicinin bunu hala optimize edebileceğini düşünüyorum.
class A
güvenemeyiz a
ve b
başlatılmayız. class C : public A
Örneğin herhangi bir uygulama, aramayı unutabilir a=0;
ve a
başlatılmamış bırakabilir .
class A { int a = 0;};
) veya temel sınıfın yapıcısında varsayılan olarak başlatmak en iyisidir . Alt sınıflar, gerektiğinde bunları yapıcılarında yeniden başlatabilir.
# 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;
}
Bu, Derived sınıf nesnesinde bulunan Base sınıf veri üyelerini başlatmak istemeniz, ancak bu değerleri Derived sınıf yapıcı çağrısı aracılığıyla arabirim oluşturmayı istemeniz durumunda çalışan bir örnektir.
Bu ender durumlarda yararlı olsa da (böyle olmasaydı, dil doğrudan buna izin verirdi), Üye deyiminden Base'e bir göz atın . Kodsuz bir çözüm değil, fazladan bir kalıtım katmanı eklemeniz gerekecek, ancak işi hallediyor. Ortak koddan kaçınmak için boost uygulamasını kullanabilirsiniz.
Neden yapamıyorsun Çünkü dil, türetilmiş sınıfın başlatıcı listesindeki temel sınıf üyelerini başlatmanıza izin vermez.
Bunu nasıl halledebilirsin? Bunun gibi:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
Bir sınıf üyesi için görünürlük belirtmezseniz, varsayılan olarak "özel" olur. Üyelerinize bir alt sınıfta erişmek istiyorsanız özel veya korumalı yapmalısınız.
Örneğinizdeki (*) A gibi toplama sınıfları, üyelerinin geneline sahip olmalı ve kullanıcı tanımlı oluşturucular içermemelidir. Başlatıcı listesiyle uyumlu hale getirilmiştir, örneğin A a {0,0};
veya sizin durumunuzda B() : A({0,0}){}
. Temel toplama sınıfının üyeleri, türetilmiş sınıfın yapıcısında tek tek başlatılamaz.
(*) Kesin olmak gerekirse, doğru bir şekilde belirtildiği gibi, özgün class A
statik olmayan üyeler nedeniyle orijinal bir toplu değildir