2013-12-17 1 views
1

에/액션 승 나는 클래스 참조는 다음과 같이 보이는 계산하게하는 믹스 인 클래스가 믹서의 소멸자에 도달했을 때 program이 더 이상 존재하지 않으므로 파생 클래스에서 last_ref_released을 호출 할 수 없지만이를 수행하는 비슷한 방법이 있습니다 (파생 클래스에 노이즈를 추가하지 않는 것이 좋습니다) ?관입 심판이 카운트 파괴

편집 : 대신 programshared_ptr<program>으로이 glUseProgram(i->get_program_name()) 같은 보일 것

class entity 
{ 
private: 
    // some other data members... 
    program prog_; 
}; 

std::vector<entity> entities_; 
for (auto& i : entities_) { 
    //i.bind_program(); 
    glUseProgram(i.get_program_name()); 

    // drawing code here... 
} 

참고 : 여기에 클라이언트 코드의 예입니다.

+0

이 구문은 무엇입니까? 'ref_count_base & operator = (ref_count_base x) &;'? – billz

+0

@billz 나는 그것을 균등 한 대입 연산자라고 부른다. 운영자는 문제가되지 않습니다. 편집 : 사실 난 그냥 문제를 발견했지만 지금은 그것을 무시하십시오. – Simple

+0

lvalues와 rvalues를 모두 받아들이는 값을 인수로 취하는 대입 연산자를 가질 수 있습니다. 그것은 복사 및 스왑을하기 위해 C++ 03에서 많이 사용되었습니다. 다시 한 번,이 특별한 경우에 문제가 있음을 알았지 만 대개는 괜찮습니다. – Simple

답변

1

편집 : 혼란 당신이 program 클래스를 계산 참조하려고하지 않는 것이 었습니다,하지만 같은 값name_참조 카운트 복사합니다.

shared_ptr 비슷한 의미로 뭔가를 만드는 깨끗한 것, 이것을 감안할 때,하지만 값 유형이 ...하자에 대한의는 shared_value 호출 : 좋아

template <typename T, void (*Deleter)(T)> 
struct shared_value { 
    typedef shared_value<T,Deleter> Self; 

    // whatever ctors, assignment operators etc. you need here: 
    shared_value(Self const &other) 
    : value_(other.value_), refs_(other.refs_) { 
     ++*refs_; 
    } 

    ~shared_value() { 
     if (resf_) { 
      if (*refs_ == 1) { 
       Deleter(value_); 
       delete refs_; 
      } 
      else 
       --*refs_; 
     } 
    } 

    operator T&() { return value_; } 
    operator T const&() const { return value_; } 
private: 
    T value_; 
    mutable int *refs_; 
}; 

및 사용 :

class program { 
    shared_value<GLuint, glDeleteProgram> name_; 
}; 

여기에 다형성 삭제자를 융통성있게 추가 할 수 있습니다 - 나는 당신에게 적합한 가장 간단한 것을 보여 줬습니다.


는 CRTP 또는 유지 mixin을 사용하거나 모든 프로그램 클래스를 건드리지 않고, 당신이 원하는 것을 할 수있는 쉬운 방법이있다.

class program { 
    GLuint name_; 

public: 
    ~program() { 
     glDeleteProgram(name_); 
    } 
}; 

을하고 현재 program를 사용하는 모든 곳에서 다음 (즉, 하나 개의 인스턴스를 생성 한 다음에 주위를 공유 포인터를 전달한다) std::shared_ptr<program>를 사용 간단하게 이런 식으로 물품.

아직 std::shared_ptr이 없으면 대신 boost::shared_ptr을 사용하십시오.

+0

내가 'shared_ptr'을 사용하지 않는 이유는 내가 '프로그램'에서 멤버 함수를 호출 할 때마다 포인터를 역 참조하고 싶지 않습니다. – Simple

+0

'shared_ptr'을 역 참조하면 캐시 미스가 발생할 가능성이 있습니다. 이 참조를 역 참조하는 것은 그렇지 않습니다. – Simple

+2

(로컬) shared_ptr에 저장된 포인터 다음에,'연산자 ->'를 통해, 원시 포인터를 따라가는 것과 어떻게 다른가? 프로그램 개체가 현재 스택 프레임에 있지 않으면 (이 경우 다시 계산할 수 없습니다) 왜 차이가 있는지 알 수 없습니다. – Useless

1

내가 이해하는 것처럼 program 클래스는 RAII 관용구를 구현하는 OpenGL 프로그램에 비해 얇은 래퍼입니다. 이 경우 refcounted 된 모든 객체에 특별한 메소드 last_ref_released()이 필요하지 않습니다. program 클래스의 소멸자에서 정리를 수행하기 만하면됩니다.

//... 
template<class D> 
ref_count_base<D>::~ref_count_base() 
{ 
    if (!refs_) 
     return; 

    if (1 == *refs_) { 
     delete refs_; /// cleaup performed there 
    } else { 
     --*refs_; 
    } 
} 


//... 
class program : private ref_count_base<program> 
{ 
private: 
    ~program() 
    { 
     glDeleteProgram(name_); 
    } 

private: 
    GLuint name_; 
};