2013-02-01 1 views
5

다음과 같은 문제가 있습니다. myClass에서 yourClass에 대한 포인터를 기본값으로 초기화하고 새 yourClass 주소로 포인터를 초기화하고 싶습니다. 불행히도, 어떤 시점에서 포인터를 삭제하려면 (코어 덤프) 얻을.C++ 기본 생성자, 새 개체를 사용하여 포인터를 초기화하는 중

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; 
} 

의 print()는 // 매개 변수에 따라 두 가지 다른 인쇄 결과가 나옵니다.

나는 yourClass yc를 고려했다. yourClass * yc 대신에 가능하지만 가능한지 알고 싶습니다.

편집 : 다음과 같은 방식으로 코드를 다시 작성했습니다. 여전히 복잡해 보입니다. 현명한 포인터는 유망 해 보입니다. 그리고 나는 여전히 "Rule of Three"를 적용하지 않았습니다. 여기에 코드가 있습니다. 모두에게 감사드립니다. 너무 많이 삭제하려고하기 때문이다

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

이것은 가능해야한다 - yourClass의 소멸자는 무엇을 포함 하는가? – 1615903

+0

오, 나는 매개 변수가있는 생성자에서 yc를 삭제해야한다고 생각하지 않습니다. – 1615903

답변

7

: 두 번째 생성자에 할당되지 않은 개체를 삭제하는

  • 을 당신이 stack-을 삭제하려고
  • (delete yc; 제거) 할당 된 객체, b. delete a;은 스택의 객체 인 b에 대한 포인터를 삭제하려고 시도합니다. 내가 발견 또 다른 문제 .. a->setMyClass(NULL)

    내가 제안 : 스마트에

    편집 (나는 예외/코어 덤프가/어떤 기대) 당신의 OS에 따라 발생 포인터

  • this blog post on RAII
  • 스택 대 힙 할당 (정적 대 동적?)을 설명하는 C/C++ 입문서
+0

두 번째 문제의 해결 방법은 'ownsYc'에 대한 플래그를 저장할 수 있습니다.이 플래그는 setMyClass()가 호출 될 때 false로 설정할 수 있으며 플래그가 true 인 경우 소멸자에서 yc 만 삭제합니다. – Crog

+0

@Crog ... ummm. .. 네,하지만 여전히 매우 위험한 디자인입니다. C++에서는 RIIA를 항상 가지고 있다고 생각합니다. 게다가, 똑똑한 포인터 (http://www.stroustrup.com/)가 있습니다. –

+1

매우 사실입니다. 안전하지 않습니다. – Crog

1

3 가지 규칙을 위반합니다.

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

tyc==yc하면 어떻게됩니까 :

What is The Rule of Three?

또한이 재해에 대한 조리법입니까? 권리. 꽤 예쁘지 않다.

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

그것은 생성자에서보다 재앙입니다 : yc는 항상 초기화되지 않습니다 : 운이 좋다면 NULL (segfault)이 삭제됩니다; 그렇지 않으면 어떤 무작위의 것을 지우는 것입니다 –

+0

어쨌든 제안하는 코드는 충돌합니다. (컴파일러가 yc를 0으로 초기화한다고 가정하십시오.) –

+1

@ dema80 동의합니다. 실제로 그 코드를 읽을 시간이 없었습니다. 부끄러운 줄 알아. 나는 약간 더 미묘하기 때문에이 고전적인 함정을 강조하겠다고 생각했다. (스캇 메이어 (Scott Meyer)조차 한때 이런 종류의 버그로 스마트 퍼를 출판했다) – sehe