2017-05-24 4 views
-3

데코레이터 디자인 패턴을 구현하고 싶습니다. 그러나, 내 코드는 Segmentation fault 오류를 제공합니다. -g 플래그를 사용하여 컴파일하려고 시도한 다음 gdb으로 확인하십시오. gdb은 오류가 action 메서드 내부의 어딘가에 있음을 보여 주지만 어디에 그리고 왜 이해가되지 않습니다.데코레이터 디자인 패턴, 분할 오류

#include <iostream> 
#include <ctime> 
#include <cstdlib> 
using namespace std; 

class CComponent 
{ 
protected: 
    int * i_array; 
    int i_size; 
public: 
    CComponent(int i_size) 
    { 
     this->i_size=i_size; 
     i_array= new int[i_size]; 
     for(int i=0; i<i_size; i++) 
     { 
      i_array[i]=0; 
     } 
    } 
    virtual int action() = 0; 
    ~CComponent() 
    { 
     delete i_array; 
    } 
    int get_i_size() 
    { 
     return i_size; 
    } 
    int get_array_at(int index) 
    { 
     return i_array[index]; 
    } 
}; 

class CConcreteCComponent : public CComponent 
{ 

public: 

    CConcreteCComponent(int i_size) : CComponent(i_size) { } 

    int action() 
    { 
     for(int i=0; i<i_size; i++) 
     { 
      i_array[i] = rand() % 100; 
      cout<< i_array[i] << " " << endl; 
     } 
     return 0; 
    } 
}; 

class Decorator : public CComponent 
{ 
protected: 
    CComponent * c; 
public: 
    Decorator(int i_size) : CComponent(i_size) 
    { 
     c = new CConcreteCComponent(100); 
    } 
    int action() 
    { 
     return c->action(); 
    } 
}; 

class CConcreteDecorator3 : public Decorator 
{ 

public: 
    CConcreteDecorator3(int i_size) : Decorator(i_size) 
    { 
    } 

    int action() 
    { 
     int w = action(); 
     for(int i=0; i<c->get_i_size(); i++) 
      if(c->get_array_at(i) % 2 == 0) 
       return w; 
     return w + 50; 
    } 
}; 

class CConcreteDecorator1 : public Decorator 
{ 
public: 
    CConcreteDecorator1(int i_size) : Decorator(i_size) 
    { 
    } 

    int action() 
    { 
     int w = action(); 

     if(c->get_array_at(0) == 0 && c->get_array_at(i_size -1) == 0) 
      return w + 100; 
     return w; 

    } 

}; 

class CConcreteDecorator2 : public Decorator 
{ 
public: 
    CConcreteDecorator2(int i_size) : Decorator(i_size) 
    { 
    } 

    int action() 
    { 
     int w = action(); 

     if(c->get_i_size() > 7) 
      return w + 150; 
     return w; 
    } 

}; 

int main() 
{ 
    Decorator * d = new CConcreteDecorator3(100); 
    Decorator * d2 = new CConcreteDecorator1(100); 
    Decorator * d3 = new CConcreteDecorator2(100); 
    int res; 

    res = d->action(); 
    cout << "res :" << res << endl; 

    return 0; 
} 
+0

'action()'내부에서'action()'을 호출하면 어떻게 될 것으로 예상됩니까? –

+0

디버거를 한 줄씩 진행할 때 관찰 한 내용은 무엇입니까? –

+1

Aside :'CComponent' 객체를 복사하거나 할당 한 경우'i_array' 포인터를 복사 한 다음 두 번 삭제할 것입니다. 소멸자가 필요하면 복사 생성자와 복사 할당 연산자도 필요합니다. ([The Rule of Three] (https://www.google.ch/search?q=rule+of+three+C%2B%2B) 참조). 또는'i_array'를'std :: vector i_array'로 바꾸면 메모리 관리에 대해 걱정할 필요가 없습니다. –

답변

2

이유는 무한한 재 등장입니다.

대신 방법 행동 에서 CConcreteDecorator3 에서 :

int w = action(); 

당신은 아마 사용해야합니다 또한

int w = Decorator::action(); 
+0

재귀가 필요 없다고하더라도 재귀가 없다는 것을 의미합니까? – mirx

+0

@mirx 기본적으로 컴파일러는 사용자가 원하는 것을 모릅니다 :) 단지 호출 할 적절한 함수를 찾습니다. 함수를 찾을 위치를 지정하지 않으면 동일한 작업 메서드가 표시되고 재귀 호출이 발생합니다. –

+0

이제 알았습니다. 고맙습니다! – mirx

0

...

  1. 귀하의 데코레이터 클래스 누출. 삭제가있는 소멸자가 없습니다.
  2. int * i_array 및 CComponent * c;에 std :: unique_ptr 대신 std::vector<int>을 사용하는 것이 좋습니다. 사용자가 피할 수 없으면 new/delete를 사용하지 않아도됩니다.
  3. CComponent에는 가상 소멸자가 필요합니다. 다형성과 가상 소멸자를 사용하면 많은 설명을 찾을 수 있습니다.
관련 문제