2012-01-22 7 views
3

최근 pure abstract classesstatic member functions을 사용하여 파생 클래스의 개체에 대한 포인터를 초기화하는 예제를 발견했습니다. 디자인 패턴인지 또는 좋은 프로그래밍 실습인지 궁금합니다.순수 추상 클래스의 정적 멤버 함수에 관한 - 디자인 패턴?

class Shape; 

typedef std::unique_ptr<Shape> shape_ptr; 

class Shape{ 

    public: 

     Shape(){}; 
     virtual ~Shape(){}; 

     virtual void draw() const = 0; 
     virtual float area() const = 0; 

     virtual shape_ptr clone() const = 0; 
     virtual shape_ptr create() const = 0; 

     static shape_ptr defineRectangle(int, int); 
     static shape_ptr defineCircle(float); 
}; 

shape_ptr Shape::defineRectangle(int height, int width){ 
    shape_ptr ptrRectangle = shape_ptr(new Rectangle(height, width)); 
    return (ptrRectangle); 
} 

shape_ptr Shape::defineCircle(float radius){ 
    shape_ptr ptrCircle = shape_ptr(new Circle(radius)); 
    return (ptrCircle); 
} 

최종 목표 derived classes의 컨테이너를 정의 할 수있다 : 다음의 코드 만 ilustration입니다 (예를 들어, defineRectangle() and defineCircle() 부재 기능 둘 다)이다. 예를 들어 :

std::vector<std::unique_ptr<Shape> > vect; 

을 한 후 우리는에 의해 컨테이너에서 파생 된 클래스를 추가 할 수 있습니다 중 하나 Shape 클래스의 정적 멤버 함수 호출 : 어떤 인터페이스없이

vect.push_back(Shape::defineCircle(10)); 
vect.push_back(Shape::defineRectangle(5, 4)); 

직접 :

vect.push_back(std::unique_ptr<Shape>(new Circle(10))); 
vect.push_back(std::unique_ptr<Shape>(new Rectangle(5,4))); 

컨테이너에서 파생 클래스를 추가하는 두 가지 방법 중 어느 것이 우선되어야하며 그 이유는 무엇입니까?
전체 코드는 다음에서 찾을 수 있습니다. link.
어떤 조명도 정말 환영합니다 ;-)

+1

,하지만 당신은 당신의'표준을 잊은 :: move' 's ... – kennytm

답변

1

std::unique_ptr이 있으므로 컴파일러가 C++ 11을 지원한다고 가정합니다.

vect.emplace_back(new Circle(10)); 
vect.emplace_back(new Rectangle(5,4)); 

(약 .emplace_back : push_back vs emplace_back)이 경우, 내가 세 번째 옵션을 제공 할 수는 shape_ptr을 반복 할 필요가 없습니다이와

을, 당신은 새를 선언 할 필요가 없습니다 새 서브 클래스를 추가 할 때마다 팩토리 메소드가 Shape으로 변경됩니다.

+0

이것도 질문에 대답하지 않습니다. –

+0

@EtiennedeMartel : 컨테이너에 파생 클래스를 추가하는 두 가지 방법 중 어느 것이 선호되어야하는지에 대한 질문에 대답하지 않는 이유는 무엇입니까? – kennytm

+0

@KennyTM : +1을 드리겠습니다 ... 전혀 모르겠습니다. 왜 내가 downvoted 중 하나를 가지고 ... 누군가가 설명하고자하는 ... – Jason

1

디자인 패턴인지 또는 좋은 프로그래밍 실습인지 궁금합니다.

예, factory pattern의 변형입니다.

기본적으로 단일 메서드를 사용할 수 있으므로 해당 메서드의 인수에 따라 올바른 파생 개체 형식이 동적으로 만들어집니다. 이렇게하면 코드에서 동일한 "팩토리"기능을 사용할 수 있으며 팩토리 메서드가 만드는 기본 객체에 변경 사항이나 추가 사항이있는 경우 실제로 "팩토리"함수를 호출하는 코드를 변경할 필요가 없습니다 . 따라서 이것은 "팩토리"를 호출하는 코드가 아니라 "팩토리"뒤에있는 코드 세그먼트에 대해 객체 생성을위한 변경 사항을 격리시키는 캡슐화 형태입니다. 예를 들어 팩토리를 사용하면 팩토리 메소드가 생성 할 수있는 새로운 유형을 추가하는 것은 상대적으로 쉽지 않지만 팩토리를 호출하는 이전 코드는 변경하지 않아야합니다. 생성하려는 새 객체에 대해 새 파생 클래스를 만들고 해당 새 객체를 원하는 새 코드에 대해 올바른 새 인수를 전달하면됩니다. 이전의 모든 인수는 여전히 작동하며 리턴 된 포인터 유형과 관련하여 코드에서 수행해야하는 변경 사항은 없습니다.

스마트 포인터를 팩토리와 함께 사용하는 이유는 메모리 누수를 피하기 위해서입니다. 포인터 소유권이 모호 할 때 발생할 수 있습니다. 예를 들어 팩토리는 객체를 역동적으로 생성하기 때문에 포인터를 반환해야합니다.그러면 포인터가 매달 리거나 메모리 누수가 발생하지 않도록 포인터를 정리하는 질문이됩니다. 스마트 포인터는이 소유권 문제를 해결하고 다른 개체가 여전히 해당 메모리를 가리키고있을 때 실수로 메모리가 정리되지 않도록하거나 해당 메모리 위치에 대한 마지막 포인터가 없으면 메모리가 손실되지 않도록 보장합니다. delete이 (가) 호출되었습니다.

+0

신경 downvote에 대한 이유를 언급? 나는 OP가 물었던 특정 질문에 대답했다고 믿고, 내가 틀렸다면, 나는 미래의 참고 문헌을 배우기를 원할 것이다 ... – Jason

+0

나는 투표하지는 않았지만,이 디자인의 문제는 그것이 위반이라고 생각한다. _single 책임 _ 원칙, Shape 객체와 Shapes와의 인터페이스를 모두 가지는 Shape. 하지만 당신은 동의 했으므로 좋은 디자인이라고 생각합니다 : ( – Lol4t0

+0

@ Lol4t0 : 팩토리 메서드가 추상 기본 클래스의 정적 메서드 인 곳을 많이 보았습니다. 파생 된 모든 파생물을 선언하는 것과 같은 몇 가지 추가 사항이 종종 있습니다. 클래스 생성자'private'을 만들고 기본 클래스를 모든 파생 클래스의 'friend'로 만들지 만, 이들은 패턴 패턴의 일반적인 디자인 대 기본 패턴의 C++ 고유 특성이라고 생각합니다. 예를 들어 Bruce Eckele "Thinking in C++ Vol II"는 팩토리 메서드를 기본 클래스의 정적 메서드로 만듭니다. – Jason

1

기술적으로 ShapeRectangle 또는 Circle에 대해 아무것도 모르기 때문에 기본 메서드에 팩터 리 메서드를 배치하는 것이 좋습니다. Donut과 같은 새 도형을 추가하면 어떻게됩니까? Shape에 새 팩토리 메소드를 추가 하시겠습니까? 당신은 인터페이스를 혼란스럽게 할 것입니다. 그래서, IMO, 두 번째 방법이 더 좋을 것입니다. 당신이 모든 시간을 shape_ptr 만들 필요의 상세를 줄이려면

, 당신은 항상 적절한 서브 클래스 팩토리 메소드 움직일 수 : 주제 오프

class Circle : public Shape 
{ 
    // ... 
public: 
    static shape_ptr make(float radius) 
    { 
     return shape_ptr(new Circle(radius)); 
    } 
}; 

// ... 

vect.push_back(Circle::make(5.0f)); 
+1

그게 팩토리 디자인 패턴의 모든 부분을 무너 뜨 렸습니다 ... 이제 정적 팩토리 메서드가있는 특정 클래스를 알아야합니다. 즉 동일한 팩터 리 메서드가 여러 파생 개체를 디스패치 할 수 없음을 의미합니다. – Jason

+0

내가 말하는 것은 공장이이 경우에도 필요하지는 않은지 아닌지입니다. –

+0

괜찮 았어.하지만 OP는 그가 말한 코드 예제가 디자인 패턴인지 물어 본다. (그는 그 다음 예제를 제시했다.) 그렇다. 공장 패턴이라고 불린다. 당신이 묘사하고있는 것은 실제로 공장 패턴이 아니며, 당신이 그것에 관해 더 명확하게해야한다고 생각합니다. 지금 당장 질문을 읽으면서 대답이 "공장 패턴을 수행하는 더 좋은 방법"이라고 말한 것처럼 들리지만 실제로는 그렇지 않습니다. – Jason

관련 문제