交叉引用并在类之间传递 this 指针 [NS2/C++]
------------ ------------
| 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()函数时。它实际上会调用基类Queue的recv()函数,而不是预期的PriQueue的recv()函数。
------------ ------------
| 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);
--------------
Dear all,
I am using NS2 to implement a network coding protocol. But I have been stuck on a problem for days regarding to cross reference between classes and the way to pass the "this" pointer.
The class hierarchy is shown in the above figure (Please excuse me it looks like that, I am a new user of this site, and is not allowed to post images).
In the program I have to create a connection from the "PriQueue" class to the "OLSR" class, which I think cross reference might be a nice way (The connection from OLSR to PriQueue is automatically set in NS2 using the pointer 'target_', which is of type NsObject*).
Part of the code is giving below.
But the problem is, the pointer "olsr_callback" is always NULL. As a result, when calling function add_rr_ack() from the PriQueue object, the line accessing the 'ra_addr_' variable will generates a segmentation error.
(The program works fine if the line "nsaddr_t addr = ra_addr();
" is blocked)
The cross reference mechanism is obtained from this page:
cross reference as stated in post 4
I guess it is the problem of the way I tried to pass the "this" pointer in send_pkt(). But I can't figure out what is wrong. If you have any idea in mind, please help me.
Any help will be appreciated.
Shu.
//------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);
.....
}
P.S: I also tried to change the recv() function in class PriQueue as follows:
//------priqueue.h------//
void recv(Packet* p, OLSR* h);
// ------priqueue.cc-----//
void PriQueue::recv(Packet* p, OLSR*h) {
......
olsr_callback = h;
......
}
//
However, in this case, when we call the recv() function from send_pkt(). It will actually invoke the recv() function of the base class Queue, not the recv() function of the PriQueue as expected.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的 OLSR 类派生自某个“代理”类(我不知道它是什么)。我认为这不是从“Handle”派生的类之一(因为它未在图中显示)。
由于“OLSR”不是从“Handle”派生的,因此“Handle”到“OLSR”的dynamic_cast 失败。您只能从多态基类到派生类进行动态转换,而不能对不相关的类进行动态转换。
You class OLSR is derived from some class 'Agent' (which I don't know what it is). I assume that is not one of those classes derived from 'Handle' (since it is not shown in the diagram).
Since 'OLSR' is not derived from 'Handle', dynamic_cast of 'Handle' to 'OLSR' fails. You can do dynamic_cast from polymorphic Base to Derived only and not to unrelated classes.
下面的代码适用于我的编译器。它输出“20”,这是我赋予成员 OLSR::ra_addr_ 的值。我必须添加一些未声明的假设才能进行编译:
recv()
,因此它不是抽象的。Packet::get()
。这只是给我一个指针,以便我可以调用与您的签名匹配的函数。如果您无法弄清楚代码不起作用的原因,请始终尝试以下操作:复制所有代码,然后一次删除一些内容,直到查明问题或获得一个简单的示例完整地发布并询问为什么它没有达到您的预期。
The code below works with my compiler. It outputs "20", which was the value I gave to the member OLSR::ra_addr_. A few unstated assumptions I had to add to get things compiling:
recv()
so that it's not abstract.Handler*
with dynamic_cast would be ill-formed, and your compiler should complain).Packet::get()
. That's just there to give me a pointer so I can call functions matching your signatures.If you can't figure out why your code isn't working, always try this: Make a copy of all your code, and then remove things a bit at a time until you either pinpoint the problem or get a simple example that you can post in entirety and ask why it doesn't do what you expect.
感谢你们所有人的帮助,Chubsdad 和 aschepler。
我已经找到问题所在了。
通常,使用以下语句将数据包安排为模拟时间轴上的事件:
其中 p 是被转换为事件的数据包; ‘0.0’是事件的延迟时间,在本例中为零;关键参数“target_”是将处理事件的处理程序。
下面是 NsObject 类的部分内容及其实现:
下面是 Handler 类的实现:
基于我之前对 NS2 的理解,我尝试使用
避免事件调度,直接调用
recv(Packet*, Handler *)
PriQueue 的函数,结果是错误的。尽管使用了
target_->recv(p,h)
,但控件仍然会进入NsObject::handle()
,作为NsObject::handle ()
函数只接受一个Event*
类型参数,Handler*
参数将始终丢失。这就是 olsr_callback 变量始终为 NULL 的原因。 (这已在我的调试过程中得到验证。)因此,下一步将对
NsObject
进行一些调整,即使我仍然不完全理解它最终如何进入函数NsObject ::recv()
当使用target_->recv(p,h)
时。 :)再次感谢您的帮助。
舒
Thank you all for your help, Chubsdad and aschepler.
I have found where the problem is.
Normally, a packet is scheduled as an event on the simulation timeline using the following statement:
where p is the packet which is casted to a event; '0.0' is the delay time of the event, in this case it is zero; and the key parameter, 'target_' is the handler which will process the event.
Here is part of the class NsObject and its implementation:
and here is the implementation of class Handler:
Based on my previous understanding about NS2, I tried to use
to avoid event scheduling, and directly call the
recv(Packet*, Handler*)
function of PriQueue, which turned out to be wrong.The control will still enter the
NsObject::handle()
,despite of usingtarget_->recv(p,h)
, as theNsObject::handle()
function takes only aEvent*
type parameter, theHandler*
parameter will always be lost. That is how theolsr_callback
variable turned out to be always NULL. (This has been verified in my debugging process.)So the next step would be make a few adjustments to
NsObject
, even if I still don't fully understand how it ends up entering functionNsObject::recv()
when usingtarget_->recv(p,h)
. :)Thanks again for your help.
Shu