2012-04-03 3 views
3

공장 :C++ : 참조와 나는 이런 식으로 뭔가가

struct D { 
    virtual void operator() {...}; 
} 
struct D1 : public D { 
    virtual void operator() {...}; 
} 
struct D2 : public D { 
    virtual void operator() {...}; 
} 

void foo(D &d) {...}; 

을 그리고이 멋지게 잘, 그리고 내 D의의 수명주기 제어 :

foo(D()); 
foo(D1()); 
foo(D2()); 

을하지만 내 D 변형을 선택 여러 곳에서 간단한 공장을 원합니다.

const D& make_D() 
{ 
    // BAD, returning reference to temporary 
    if(is_tuesday()) 
     return D1(); 
    return D2(); 
} 

임시 참조를 반환하는 대신 obje를 반환 할 수 있습니다. CT하지만 기본 클래스로 슬라이스합니다. 또는 공장에서 포인터를 반환 할 수 있지만 클라이언트가 포인터를 삭제해야합니다. 다른보다 복잡한 솔루션은 클라이언트에 더 많은 부하를 부과합니다.

D& d = make_D(); 
foo(d); 

(또는 foo(make_D())) 같은 것을 쓸 수있는 방법이 있나요? 목표는 다양한 D 정의와 make_D()에서 복잡성을 감싸서 foo()과 같은 함수와 그 함수를 호출하는 함수가 걱정할 필요가 없도록하는 것입니다.

+0

참고 : 임시가 비 const 값 참조에 바인딩 될 수 없기 때문에'foo (D())'는 컴파일되지 않습니다 (컴파일러가 아닌 컴파일러는 비표준 동작에 대한 경고를 내 보냅니다). . –

답변

5

일반적인 방법은 포인터 또는 스마트 포인터를 반환하는 것입니다.

포인터를 사용하면 사용자가 메모리를 관리 할 수 ​​있다는 단점이 있습니다.

스마트 포인터를 반환하면 더 이상 문제가되지 않습니다.

const SmartPtr<D> make_D() 
{ 
    if(is_tuesday()) 
     return SmartPtr(new D1()); 
    return SmartPtr(new D2()); 
} 
5

불행히도, 불가능합니다.

보통, 내가 무엇을 할 것은 (이 std::unique_ptr을 사용할 수없는 경우, 때때로 std::shared_ptr) std::unique_ptr을 사용하는 것입니다

typedef std::unique_ptr<D> Dptr; 
Dptr make_D() 
{ 
    Dptr p(nulptr); 

    if(is_tuesday()) 
     p.reset(new D1); 
    else 
     p.reset(new D2); 

    return p; 
} 
0

첫째, 내가 이해도 확실하지 않다. 나열한 코드가 이 아니므로 컴파일되지 않습니다.

struct D 
{ 
    virtual void operator()() const { /* ... */ } 
}; 

과 :

void foo(D const& d) { /* ... */ } 

호출, 또는 변경할 수 있습니다 당신은 아니라고 확신합니까? 아마도 인수를 전달하지 않았으므로 사용하지 않으면 객체를 버리게됩니다. 그렇지 않으면 은 정적 인스턴스에 대한 참조를 간단히 반환 할 수 있습니다. 이것은 제가 사용하는 일반적인 솔루션입니다. 그렇지 않으면 복사 가능 객체 을 letter envelop idiom 문자를 사용하여 다형성으로 동작시킬 수 있지만 일반적으로 은 각 복사본에 대해 실제 객체의 복제가 필요하기 때문에 약간의 런타임 오버 헤드가 발생합니다 ( ).

관련 문제