Soru C ++: DerivedClass'ın kurucusunun neden BaseClass'ın korunan alanına erişimi yok?


Bir temel sınıftaki bir alanı başlatmaya çalışan bir kurmacam var. Derleyici şikayet ediyor. Alan korunur, bu nedenle türetilmiş sınıfların erişimi olmalıdır.

//The base class: 

class BaseClass

{

public:

    BaseClass(std::string);
    BaseClass(const BaseClass& orig);
    virtual ~BaseClass();
    const std::string GetData() const;
    void SetData(const std::string& data);
protected:

    BaseClass();
    std::string m_data;

};

BaseClass::BaseClass(const std::string data) : m_data(data) { }

BaseClass::BaseClass() { } 

BaseClass::BaseClass(const BaseClass& orig) { }

BaseClass::~BaseClass() { }

void BaseClass::SetData(const std::string& data)
{
    m_data = data;
}

const std::string BaseClass::GetData() const
{
    return m_data;
}


//The derived class: 


class DerivedClass : public BaseClass
{

public:

    DerivedClass(std::string data);
    DerivedClass(const DerivedClass& orig);
    virtual ~DerivedClass();
private:

};

DerivedClass::DerivedClass(std::string data) : m_data(data) { } //ERROR HERE

DerivedClass::DerivedClass(const DerivedClass& orig) { }

DerivedClass::~DerivedClass() { }

// Derleyici hatası

DerivedClass.cpp: 3: error: class "DerivedClass" sınıfında "m_data" adında bir alan yok

Herhangi bir yardım büyük beğeni topluyor. Şimdiden teşekkür ederim.


25
2017-07-23 15:51


Menşei


Teşekkürler beyler. Bu gerçekten yardımcı oldu! - Ruairi Hourihane


Cevaplar:


Türetilmiş sınıf yapıcısında m_data'yı başlatamazsınız, bunun yerine temel sınıf yapıcısına bir argüman olarak iletemezsiniz.

Yani: DerivedClass::DerivedClass(std::string data) : BaseClass(data) { }


42
2017-07-23 15:56



+1. Daha güçlü yapmamalı. Aslında yapamam. - JaredPar
Doğru cevabı güncelledim. - Zitrax
Bu, teşekkür ederim! - dwinchell
Bunun ne kadar yardımcı olduğu hakkında hiçbir fikrin yok - J3STER


Başlatıcı listesinde, aynı sınıfın niteliklerine ilişkin değerleri ayarlayabilirsiniz. Ona erişmek için, yapıcının gövdesindeki değeri atlamanız gerekir:

DerivedClass :: DerivedClass (std :: string data) {m_data = veri; }

Veya, nesneyi kopyalamak pahalıysa, m_data'yı üst sınıf yapıcısına bir argüman olarak iletirsiniz:

DerivedClass :: DerivedClass (std :: string data): Temel Sınıf (veri) {}

İpucu: Kopya oluşturucuyu önlemek için verilerinizi referans olarak iletin.

Daha fazla bilgi için buraya bakın: C ++ kurucularının başlatılması sırası.


7
2017-07-23 16:00





M_data'ya "erişmiyorsunuz" - başlatıyorsunuz. Ancak, zaten Temel Sınıfın ctorunda başlatılmıştır. Değerini değiştirmek isterseniz, ctorunuzun bedenine atayın:

DerivedClass::DerivedClass(std::string data) 
{
   m_data = data;
}

4
2017-07-23 16:00





Temel sınıf kurucusunu şu şekilde çağırmanız gerekir:

DerivedClass::DerivedClass(std::string data) : BaseClass(data) {
}

Her sınıf, üyelerini başlatmaktan sorumlu olmalıdır.


1
2017-07-23 16:01





Başlatıcı listeleri sadece söz konusu türe ait olan alanları başlatmak için kullanılabilir. Temel hata alanlarını bir başlatıcı listelerinde başlatmak yasal değildir, bu nedenle bu hatayı alırsınız. Alan başka şekilde erişilebilir DerivedClass


0
2017-07-23 15:59





Türetilmiş sınıf yapıcınız erişim hakkına sahip, ancak başlatma listesinde onu atayamazsınız. Yapıcıyı şu şekilde değiştirin:

DerivedClass::DerivedClass(const std::string& data)
 : BaseClass(data)
{
}


0
2017-07-23 16:00