C++のスマートポインタ使った状態管理についての質問です。
自身のポインタを戻り値としたClass* Class::Update()関数で状態を管理するプログラムをshared_ptr<Class>を用いて書きたいのですが、
shared_ptr<Class> class class.reset(class->Update())という書き方だとアクセス違反となってしまいます。
この原因が分かりません。スマートポインタの仕様でclass変数が解放されているのでしょうか?
どうかご教授お願い致します。
下記の例のプログラムは、CSMA/CAのシミュレーションを作っています。
以下 struct Channelとstruct ChannelStateを使ったプログラム例(一部割合)
Channel.h
/*通信路クラス*/ struct Channel { public: static shared_ptr<Channel> channel; /*シングルトン*/ static list<shared_ptr<PassChannel>> TerminalList; /*端末情報*/ static list<shared_ptr<Packet>> packets; /*通信路に送られたパケット*/ Channel(); void Update(); private: shared_ptr<ChannelState> state; //通信路の状態 };
Channel.cpp
void Channel::Update() { state.reset(state->Update()); //アクセス違反 return; }
ChannelState.h
/*通信路状態の基底クラス*/ struct ChannelState { public: ChannelState(); virtual ChannelState* Update(); }; /*パケット送信可能状態*/ struct Idle:public ChannelState { public: Idle(); ChannelState* Update() override; }; /*パケット送信中状態*/ struct Busy:public ChannelState { public: Busy(); ChannelState* Update() override; private: shared_ptr<Packet> packet; int Counter; }; /*衝突発生*/ struct Collision :public ChannelState { public: Collision(); ChannelState* Update() override; };
ChannelState.cpp
ChannelState* Idle::Update() { if ((int)Channel::packets.size()==1) { return new Busy(); } else if ((int)Channel::packets.size()>1) { return new Collision(); } return this; } ChannelState* Busy::Update() { Counter++; if (Counter == packet->transferTime) { list<shared_ptr<PassChannel>>::iterator itr; itr = Channel::TerminalList.begin(); while ((*itr)->GetID() != packet->distination) { itr++; } (*itr)->ReceivePacket(packet.get()); return new Idle(true); } return this; } ChannelState* Collision::Update() { if ((int)Channel::packets.size()==1) { return new Busy(); } else if (Channel::packets.size() >= 1) { return new Collision(); } return this; }
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/10/18 16:03