2016-12-01 10 views
1

CRTP 나는 순수 가상 클래스 <code>Interface</code>의 원인이 segfault의

template<typename T> 
class AbstractInterface : public Interface { 
    public: 
    void open() override; 
    void close() override; 
    void read_is_complete(const vector<byte_array>); 
    protected: 
    explicit AbstractInterface(const string params); 
    virtual ~AbstractInterface() noexcept; 
} 

그런 다음 인터페이스의 구현이를 그 다형성을 위해 CRTP를 사용합니다 :

class SPInterface : public AbstractInterface<SPInterface> { 
    public: 
    explicit SPInterface(const string params); 
    virtual ~SPInterface() noexcept; 
    void open(); 
    void close(); 
    void read_is_complete(const vector<byte_array> data); 
} 

나는 insta SPInterface의 NCE :

unique_ptr<Interface> intf; 
intf.reset(new SPInterface("aaa")); 

이 범위를 벗어나 분들께 차례로 AbstractInterface에 close 메소드를 호출하는 소멸자 AbstractInterface를 호출 한 후이 this에 세그먼테이션 폴트 (segfault) : 이미 I로 혼란

template<typename T> 
void AbstractInterface<T>::close() { 
    static_cast<T *>(this)->close(); 
    params_ = ""; 
} 

클래스의 인스턴스를 만들었습니다. lldb 확인을 위해 보인다

AbstractInterface<SPInterface>::close(this=<unavailable>) 
+2

기본 클래스의 소멸자에서 파생 클래스의 메서드를 호출하려고해도 안전합니까? – skypjack

+1

나는 당신이 거기에 요점을 가지고 있다고 생각합니다 :) – ruipacheco

답변

3

이 범위를 벗어나 분들께 것은 다시 AbstractInterface에 close 메소드를 호출하는 소멸자 AbstractInterface 호출 한 후이에 세그먼테이션 폴트 (segfault) :

template<typename T> 
void AbstractInterface<T>::close() { 
    static_cast<T *>(this)->close(); 
    params_ = ""; 
} 

기본 클래스의 소멸자 내에서 파생 클래스의 메서드를 호출하는 것 같습니다.
이것은 전혀 안전하지 않으며 segfault은 실행 파일이 승인하지 않는다는 것을 알려주는 방법입니다. :-)

CRTP를 사용하면 살아있는 객체에 파생 클래스에 속한 멤버 함수를 호출 할 수 있지만 객체가 파괴되는 방식은 변경되지 않습니다.
베이스와 멤버가 생성자의 완료와 반대 순서로 삭제된다는 것을 잊지 마십시오.