0

オブザーバー パターンは、Cython バインディングを介して Python インタープリターに公開したいと考えている私の C++ プロジェクトに頻繁に現れます。状況を示す最小限の例を作成しようとしました。は、 などSpectacleの抽象基本クラスから派生した任意のオブジェクトを受け入れます。を呼び出すと、登録されている各オブザーバーに通知されます。ObserverOnlookerSpectacle::event()

これはファイルの内容ですObserverPattern.h:

class Spectacle {
private:
    std::vector<Observer*> observers;
public:

    Spectacle() {};
    virtual ~Spectacle() {};

    virtual void registerObserver(Observer* observer) {
        this->observers.push_back(observer);
    }

    virtual void event() {
        std::cout << "event triggered" << std::endl;
        for (Observer* observer : this->observers) {
            observer->onEvent();
        }
    }
};

class Observer {
public:
    Observer() {};
    virtual ~Observer() {};
    virtual void onEvent() = 0;

};

class Onlooker : public Observer {
public:
    Onlooker() {};
    virtual ~Onlooker() {};
    virtual void onEvent() {
        std::cout << "event observed" << std::endl;
    }
};

そして、これは.pyxバインディングを含む私のファイルの内容です:

    cdef extern from "ObserverPattern.h":
        cdef cppclass _Spectacle "Spectacle":
            _Spectacle() except +
            void registerObserver(_Observer* observer)
            void event()

    cdef extern from "ObserverPattern.h":
        cdef cppclass _Observer "Observer":
            _Observer() except +
            void onEvent()

    cdef extern from "ObserverPattern.h":
        cdef cppclass _Onlooker "Onlooker":
            _Onlooker() except +
            void onEvent()

    cdef class Spectacle:
        cdef _Spectacle _this

        def event(self):
            self._this.event()

        def registerObserver(self, Observer observer):
            self._this.registerObserver(observer._this)

   cdef class Observer:
        cdef _Observer* _this   # must be a pointer because _Observer has pure virtual method

    cdef class Onlooker(Observer):
        pass   # what should be the class body?

これはコンパイルされますが、event()呼び出されてオブザーバーに通知されるとセグメンテーション違反が発生します。

>>> spec = CythonMinimal.Spectacle()
>>> look = CythonMinimal.Onlooker()
>>> spec.registerObserver(look)
>>> spec.event()
event triggered
Segmentation fault: 11

ここでの問題は何ですか?修正はどのように見えるでしょうか?

4

1 に答える 1