2013-02-01 25 views
5

Aşağıdaki sorunla karşılaşıyorum: myClass içinde bir işaretçiyi, yeni bir ClassClass adresinizle kendi Class'ınıza varsayılan olarak başlatmak istiyorum. Maalesef, işaretçiyi herhangi bir noktada silmek istersem, (çekirdek dökümü) alıyorum.C++ varsayılan kurucu, yeni nesneyle başlatıcı başlatılıyor

class myClass 
{ 
     protected: 
     yourClass * yc; 

     public: 
     myClass() { yc = new yourClass(); } 

     myClass(yourClass * tyc) { delete yc; yc = tyc; } 

     ~myClass() { delete yc; yc = NULL; } 

     void setMyClass (yourClass * tyc) { delete yc; yc = tyc; } 

     void print() { yc->print(); } 
}; 

int main() 
{ 
    yourClass b (//parameter); 
    myClass * a = new myClass(); 
    a->print(); 
    a->setMyClass(&b) 
    a->print(); 

    delete a; 
    return 0; 
} 

a (a) baskısı, // parametrelere bağlı olarak iki farklı baskıyla sonuçlanmalıdır.

Sınıfınızı; yourClass * yc yerine, ancak mümkün olup olmadığını bilmek istiyorum.

DÜZENLEME: Kodu aşağıdaki şekilde çalıştırdım ve çalışıyor. Hala karmaşık görünüyor, akıllı işaretçiler umut verici görünüyor ve hala "Üç Kuralı" uygulanmadı. İşte kod. Hepinize teşekkürler. Çok fazla silmeye çalışıyorsunuz çünkü var

class myClass 
{ 
     protected: 
     yourClass * yc; 
     bool dynamic; 

     public: 
     myClass() { dynamic = true; yc = new yourClass(); } 
     myClass (yourClass * tyc) 
     { 
      // dynamic init (like default) 
      if (tyc == NULL) { dynamic = true; yc = new yourClass(); } 
      // static use of yc 
      else { dynamic = false; yc = tyc; } 
     } 
     // because only if dynamic is true, we need to erase 
     ~blu() { if (dynamic) { delete yc; dynamic = false; } } 

     void setMyClass(yourClass* tyc) 
     { 
      // leaving unchanged if new-stuff is NULL or like old-stuff 
      if (tyc == yc || tyc == NULL) return; 
      else // treating dynamic and static differently 
      { 
      if (dynamic) // if flag is set, must be deleted 
      { 
       delete yc; yc = tyc; dynamic = false; 
      } 
      else // must not be deleted, dynamic is still false 
      { 
       yc = tyc; 
      } 
      } 
     } 
     void print() { yc->print(); } 
}; 
+0

Bu mümkün olmalıdır - Sınıfınızın yıkıcısı ne içerir? – 1615903

+0

Oh ve parametreli kurucuda yc'nin silinmesi gerektiğini sanmıyorum. – 1615903

cevap

7

: Eğer ikinci yapıcı olmayan bir tahsis nesnesi siliyorsunuz

  • Bir stack- silmeye çalışıyorsunuz
  • (delete yc; kaldırmak) ayrılmış nesne, b. delete a;, bir işaretçiyi b üzerinde silmeyi deneyecektir; Ben benekli başka bir sorun .. a->setMyClass(NULL)

    öneririm: akıllı üzerine

    DÜZENLEME (Ben bir istisna/çekirdek döküm/ne olursa olsun bekliyoruz) OS bağlıdır olur işaretçiler

  • this blog post RAII üzerinde
  • herhangi bir C/C++ primer yığın veya yığın ayırma açıklayan (statik vs dinamik?)
+0

İkinci sorun için bir çalışma, setMyClass() çağrılırken false olarak ayarlayabileceğiniz 'ownsYc' için bir bayrak depolamak ve bayrak true – Crog

+0

@Crog ... ummm ise yalnızca yok edicideki yc'yi silmek olabilir. .. evet, ama yine de çok, çok tehlikeli bir tasarım. C++ 'da, RIIA'ya sahip olmak her zaman daha iyi olduğuna inanıyorum; Ayrıca, akıllı işaretçiler var (http://www.stroustrup.com/) –

+1

Çok doğru, güvenli değil. – Crog

1

Üçün kuralını ihlal ediyorsunuz.

myClass(yourClass * tyc) { delete yc; yc = tyc; } 

tyc==yc ederse ne olur:

What is The Rule of Three?

Ayrıca, bu felaket için tarifi nedir? Sağ. Pek tatlı değil :)

myClass(yourClass * tyc) { if (yc!=tyc) { delete yc; yc = tyc; } } 
+0

bundan daha fazla felakettir :) kurucuda yc her zaman başlatılmayacaktır: eğer şanslıysanız, NULL (segfault); Aksi takdirde, –

+0

bazı rasgele-şey silmek Bu yüzden teklif ettiğiniz kod zaten çökecektir (derleyici sıfırlamak yc 0 ...) –

+1

@ dema80 Katılıyorum, aslında bu kodu okumak için zaman yoktu. Utanmalısın üzerimde. Bu klasik tuzağı vurgulayacağımı düşündüm, çünkü biraz daha incelikli (Scott Meyer bir keresinde bir kitapta bu tür bir böcekle bir smartptr yayınladı bile) – sehe

İlgili konular