------------ ------------
| TclObjct | | Handler |
------------ ------------
|__________________________________|
|
--------------
| NsObject |---> virtual void recv(Packet*,Handler* callback = 0) = 0;
--------------
|
--------------
| Connector |
--------------
|
________________________________
| |
| -------------
| | Agent |
| -------------
| |
| -------------
| | OLSR |
------------- -------------
| Queue |-----> virtual void recv(Packet*, Handler*);
-------------
|
-------------
| DropTail |
-------------
|
-------------
| PriQueue |-----> void recv(Packet* p, Handler* h);
--------------
親愛なる、私は NS2 を使用してネットワーク コーディング プロトコルを実装しています。しかし、クラス間の相互参照と「this」ポインターを渡す方法に関して、私は何日も問題に悩まされてきました。
クラス階層は上の図のようになっています (そのように見えて申し訳ありません。私はこのサイトの新規ユーザーであり、画像の投稿は許可されていません)。
プログラムでは、「PriQueue」クラスから「OLSR」クラスへの接続を作成する必要がありますが、これは相互参照が良い方法だと思います (OLSR から PriQueue への接続は、ポインタ「target_」を使用して NS2 で自動的に設定されます)。 、これはタイプ NsObject* です)。
コードの一部を以下に示します。しかし問題は、ポインター「olsr_callback」が常に NULL であることです。その結果、PriQueue オブジェクトから関数 add_rr_ack() を呼び出すと、「ra_addr_」変数にアクセスする行でセグメンテーション エラーが発生します。
nsaddr_t addr = ra_addr();
(行 " " がブロックされていれば、プログラムは正常に動作します)
相互参照メカニズムは、このページから取得されます: 投稿 4 に記載されている相互参照
send_pkt() で「this」ポインタを渡そうとした方法の問題だと思います。しかし、何が悪いのかわかりません。何か心当たりがあれば、ご協力お願いします。
どんな助けでも大歓迎です。
シュウ。
//------OLSR.h--------//
class PriQueue;
class OLSR : public Agent {
......
nsaddr_t ra_addr_;
void send_pkt();
......
public:
inline nsaddr_t& ra_addr() { return ra_addr_; }
Packet* add_rr_ack(Packet*,PriQueue*);
......
}
//------OLSR.cc------//
#include<olsr/OLSR.h>
#include<queue/priqueue.h>
void OLSR::send_pkt() {
......
......
target_->recv(p,this); // 'target_' points to the respective priqueue object
// during the runtime
}
Packet* OLSR::add_rr_ack(Packet* p, PriQueue*) {
......
nsaddr_t addr = ra_addr(); // Generate a segmentation error!!!!!
.......
return p;
}
......
//------priqueue.h------//
class OLSR;
class PriQueue : public DropTail {
public:
void recv(Packet* p, Handler* h);
......
Packet* deque();
OLSR* olsr_callback;
......
}
//------priqueue.cc------//
#include<olsr/OLSR.h>
#include "priqueue.h"
PriQueue::PriQueue() : DropTail(),olsr_callback(NULL) {......}
PriQueue::recv(Packet* p, Handler* h) {
......
olsr_callback = dynamic_cast<OLSR*>(h);
//Debug
printf("Packet received through recv() in PriQueue. \n");
......
}
PriQueue::deque() {
.....
Packet* p = q_->deque();
if(olsr_callback == NULL) printf("CALLBACK is NULL. \n");
Packet* p1 = olsr_callback->add_rr_ack(p);
.....
}
PS: クラス PriQueue の recv() 関数も次のように変更しようとしました。
//------priqueue.h------//
void recv(Packet* p, OLSR* h);
// ------priqueue.cc-----//
void PriQueue::recv(Packet* p, OLSR*h) {
......
olsr_callback = h;
......
}
// ただし、この場合、send_pkt() から recv() 関数を呼び出すとき。実際には、PriQueue の recv() 関数ではなく、基本クラス Queue の recv() 関数を呼び出します。