0
using namespace std;

class Layer
{
protected:
    Layer *lower;
    Layer *upper;
public:
    Layer(Layer *lo,Layer *up):lower(lo),upper(up)
    {}
    virtual void send()=0;
    virtual void receive()=0;
};
class Physical_Layer:public Layer
{
public:
    Physical_Layer(Layer *p):Layer(NULL,p)
    {
        cout<<"Physical_Layer constructed"<<endl;
    }
    virtual void send()
    {
        cout<<"Data send from Physical_Layer"<<endl;
        receive();
    }
    virtual void receive()
    {
        cout<<"Physical_Layer calling receive of DataLink_Layer"<<endl;
        upper->receive();
    }
};
class DataLink_Layer:public Layer
{
public:
    DataLink_Layer(Layer *p):Layer(new Physical_Layer(this),p)
    {
        cout<<"DataLink_Layer Constructed"<<endl;
        lower->send();
    }
    virtual void send()
    {
        cout<<"Data send from DataLink_Layer"<<endl;
        lower->send();
    }
    virtual void receive()
    {
        cout<<"DataLink_Layer calling receive of Application_Layer"<<endl;
        cout<<typeid(upper).name()<<endl;



        upper->receive();



    }
};
class Application_Layer:public Layer
{
public:
    Application_Layer():Layer(new DataLink_Layer(this),NULL)
    {
        cout<<"Application_Layer Constructed"<<endl;
        send();
    }
    virtual void send()
    {
        cout<<"Sending data from Application_Layer"<<endl;
        lower->send();
    }
    virtual void receive()
    {
        cout<<"Receiving data at Application_Layer"<<endl;
    }
};

int main()
{
    Layer *l=new Application_Layer();
}

プロトコルデザインパターンを使用して、3層のプロトコルスタックをシミュレートしようとしました。しかし、DataLink_Layerの受信でupper-> receiveを逆参照しているときに、実行時例外System.AccessViolationExceptionが発生します。なぜ私はそれを手に入れているのですか?

4

1 に答える 1

3

のコンストラクターは、 の基本クラスが構築される前に、経由で aDataLink_Layerにコールバックしようとしています (この時点ではまだ を評価しています)。Application_LayerLayer*LayerApplication_Layernew DataLink_Layer(this)

コンストラクターを呼び出すだけupper->receive()で、これをより明確に確認できます。DataLink_Layer

このFAQthisでは、コンストラクターでの使用についてもう少し説明しています。

この単純な例は、問題をより明確に示している可能性があります。

struct C;
struct A
{
    A(C* c) {};
    virtual void Foo() = 0;
};

struct C
{
    C(A* a)
    {
        a->Foo();
    }
};

struct B : public A
{
    B() : A(new C(this)) {}
    void Foo() {}
};

int main()
{
    B b;
}

一般に、コンストラクターを使用して、部分的に構築されたオブジェクトに対して複雑なコール スタックを実行しないでください。send()構築後にorreceive()関数を明示的に呼び出すだけです。

于 2013-01-09T04:51:09.397 に答える