2011-03-23 2 views
0

현재 프로젝트에는 스크립트 환경에 안전하게 노출시키기 위해 C++ 객체를 추적/프록시하는 메커니즘이 있습니다. 이 함수의 일부는 C++ 객체가 파괴되었을 때 알려 주어 스크립트 환경에서 객체에 대한 참조를 안전하게 정리할 수 있도록합니다.소멸자에서 sigC++ 신호를 방출하는 것이 안전합니까?

class DeleteEmitter { 
public: 
    virtual ~DeleteEmitter() { 
     onDelete.emit(); 
    } 
    sigc::signal<void> onDelete; 
}; 

그때 스크립트 환경에 노출 될 필요가있다 모든 클래스가이 클래스에서 상속이를 달성하기

, 나는 다음과 같은 클래스를 정의했습니다. 프록시 계층이 호출 될 때 콜백을 onDelete 신호에 연결하기 때문에 객체가 삭제 될 때이를 알립니다.

라이트 테스트에서는이 방법이 작동하지만 실제 테스트에서 코드의 관련없는 부분에서 고유 한 메모리 손상 (읽기 : malloc/free에서 충돌)이 발생합니다. valgrind에서 실행하면 해지 된 객체를 두 번 사용하지 않거나 계속 사용할 수 있으므로 상속 계층 구조에 DeleteEmitter를 추가 한 후에 만 ​​노출되는 클래스에 오래된 버그가있을 가능성이 있습니다.

내 조사 과정에서 소멸자가 발생하는 동안 sigC++ 신호를 방출하는 것이 안전하지 않을 수도 있습니다. 분명히 콜백이 삭제되는 객체를 사용하려고 시도하면 나쁜 일이지만, 여기서 일어나는 일이 아니라는 것을 확인할 수 있습니다. 이것을 가정하면, 이것이 안전한지를 알 수 있습니까? 동일한 결과를 얻기위한보다 일반적인 패턴이 있습니까?

답변

2

C++ 스펙은 소멸자가 반환 할 때까지 객체의 데이터 멤버가 파괴되지 않도록 보장하므로 해당 시점에서 onDelete 객체는 변경되지 않습니다. 신호가 간접적으로 파괴되고있는 객체 (다른 객체의 일부인 경우 여러 객체)에 대한 읽기, 쓰기 또는 메서드 호출을 간접적으로 발생시키지 않거나 C++ 예외를 생성하지 않는다고 확신하는 경우 "안전합니다 . " 물론 다중 스레드 환경이 아니라고 가정하면 다른 스레드가 간섭하지 않도록해야합니다.

+0

'onDelete.emit()'이 진행되는 동안 객체는 여전히 정상적으로 존재하므로 던지지 않는 한 안전합니다. – Puppy

관련 문제