2016-04-07 27 views
5

Ben 2 sınıfları, A ve B var. A'da 3 özel alanım var. B sınıfında bir kopya oluşturucu yazmak ve özel alanları A sınıfından başlatmak istiyorum. Ben protected için private den değiştirdiğinizde o iş (ve tabii ki, çalışır) gerektiğini anlamak DOMiras ve kopya kurucu - özel alanların temel sınıftan nasıl başlatılacağı?

#include <iostream> 
#include <string> 
using namespace std; 

class A 
{ 
    private: 

     string *field1; 
     string *field2; 
     string *field3; 
     double num1; 

    public: 

     A(string *o, string *n, string *m, double a=0) 
     { 
      field1 = new string(*o); 
      field2 = new string(*n); 
      field3 = new string(*m); 
      num1 = a; 
     } 

     A(const A& other) { 
      field1 = new string(*other.field1); 
      field2 = new string(*other.field2); 
      field3 = new string(*other.field3); 
      num1 = other.num1; 
     } 

     void show() 
     { 
      cout << *field1 << " " << *field2 << " " << *field3 << "\n"; 
     } 

     ~A() 
     { 
      delete field1; 
      delete field2; 
      delete field3; 
     } 
}; 

/*--------------------------------------------------------------------------------------------*/ 

class B : public A 
{ 
    private : 

     double num2; 
     double num3; 

    public: 

     B(double num2, double num3, string *o, string *n, string *num, double a=0) : A(o,n,num,a) 
     { 
      this->num2 = num2; 
      this->num3 = num3; 
     } 

     B(const B& other) : A(other.field1, other.field2, other.field3, other.num1) 
     { 
      num2 = other.num2; 
      num3 = other.num3; 
     } 

     void show() 
     { 
      cout << num2 << " " << num3 << "\n"; 
      A::show(); 
     } 
}; 

int main() 
{ 
    string o = "TEXT 111"; 
    string *optr = &o; 

    string n = "TEXT 222"; 
    string *nptr = &n; 

    string *numptr = new string("9845947598375923843"); 

    A ba1(optr, nptr, numptr, 1000); 
    ba1.show(); 

    A ba2(ba1); 
    ba2.show(); 

    A ba3 = ba2; 
    ba3.show(); 

    B vip1(20, 1000, optr, nptr, numptr, 3000); 
    vip1.show(); 

    B vip2(vip1); 
    vip2.show(); 

    delete numptr; 
    return 0; 
} 

- ama nasıl benim kodunda sahip durumla başa çıkmak için: Ancak, bu çalışmıyor? Soru şudur: kopyalama kurucusunda, temel sınıftaki özel alanlar nasıl başlatılır? Ben şimdiki koduyla aşağıdaki hataları alıyorum:

/home/yak/test.cpp|9|error: ‘std::string* A::field1’ is private| 
/home/yak/test.cpp|61|error: within this context| 
/home/yak/test.cpp|10|error: ‘std::string* A::field2’ is private| 
/home/yak/test.cpp|61|error: within this context| 
/home/yak/test.cpp|11|error: ‘std::string* A::field3’ is private| 
/home/yak/test.cpp|61|error: within this context| 
/home/yak/test.cpp|12|error: ‘double A::num1’ is private| 
/home/yak/test.cpp|61|error: within this context| 
||=== Build failed: 8 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===| 
+1

Sen önerdiğiniz olarak onları 'protected' ardından B'nin ctor vücuttan bunlara erişmek olun. Onları korumalı hale getirmenin problemi nedir? – RJFalconer

+0

Eğer 'A' değiştiremezseniz, o zaman ne soruyorsunuz? Ve kodunuz sızıyor ve istisnada güvenli değil. İşaretçiler dizeleri neden kullanmalı ?! –

+0

@RJFalconer: Merak ediyorum, özel ders alanlarını çocuk sınıfından başlatmak için ne yapmam gerekiyor. Gördüğümüz gibi, başlangıç ​​listesi ile – yak

cevap

6

yapmanız gereken tek şey A kopyası yapıcısı çağırmak.

Ayrıca bu göstergesinin tüm gereksizdir ve kod daha karmaşık hale unutmayın. Biz gibi yazabilirsiniz:

class A 
{ 
private: 
    string field1; 
    string field2; 
    string field3; 
    double num1; 

public: 
    A(const string& o, const string& n, const string& m, double a = 0) : field1(o), field2(n), feild3(m), num1(a) {} 

    A(const A& other) field1(other.field1), field2(other.field2), feild3(other.feild3), num1(other.num1) {} 

    void show() 
    { 
     cout << field1 << " " << field2 << " " << field3 << "\n"; 
    } 
}; 

/*--------------------------------------------------------------------------------------------*/ 

class B : public A 
{ 
private: 

    double num2; 
    double num3; 

public: 

    B(double num2, double num3, const string& o, const string& n, const string& m, double a = 0) : A(o, n, num, a), num2(num2), num3(num3) {} 

    B(const B& other) : A(other), num2(other.num2), num3(other.num3) {} 

    void show() 
    { 
     cout << num2 << " " << num3 << "\n"; 
     A::show(); 
    } 
}; 
+0

'A', 'diğer' nin neyi 'kopyaladığını' nasıl bilmeli? Çünkü A'da bir kopya kurucum var? – yak

+0

@yak Bu ve [nesne dilimleme] (http://stackoverflow.com/questions/274626/what-is-object-slicing) (burada bir sorun değil). – LogicStuff

+0

@LogicStuff: Teşekkür ederiz – yak

0

Sen bunu aynı argümanı vererek, kopya kurucu gelen ana kopya kurucu çağırmak gerekir. Bunun yasal olduğuna ve Aother ait A bölümünü kopyalar A den BB yana

B(const B& other) : A(other) 
{ 
    num2 = other.num2; 
    num3 = other.num3; 
} 

gibi devralır inşa kopyalarken

1

sınıf B için kopya kurucu kullanılarak, sen

Yani A sınıfı için kopya kurucu dediğimiz bu tek kodunuzu değiştirmesi gerekir:

B(const B& other) : A(other) 
    { 
     num2 = other.num2; 
     num3 = other.num3; 
    } 

Ayrıca, yok edici sınıfı A sınıfından sanal olarak bildirin. Ve sanırım bunu show() yöntemi için de yapmak istersiniz.

İlgili konular