title: 6、NS中的回调
tags: NS-3,C++,Simulation,Callback,Function Pointer
slug: storywriter/upgrade_log
grammar_mindmap: true
renderNumberedHeading: true
grammar_code: true
grammar_decorate: true
grammar_mathjax: true
NS3中的回调(callback.cc)
NS3中的回调
普通函数的回调|(FunctorCallbackImpl)
BoundFunctorCallbackImpl
方法的回调|(MemPtrCallbackImpl)
BoundMemPtrCallbackImpl
具体的实现
MakeCallback()
MakeBoundCallback()
普通函数的回调(FunctorCallbackImpl)
- 回调的类型:Callback<对应函数的返回值类型,....>
- MakeCallback()函数来创建一个回调对象
Callback<int, int, int> callback = MakeCallback(&add);
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
#include "ns3/core-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TryCallback");
class A {
public:
A(Callback<int, int, int> calculator);
void calculate();
private:
Callback<int, int, int> m_calculator;
};
A::A (Callback<int, int, int> calculator)
{
m_calculator = calculator;
}
void
A::calculate ()
{
int result = m_calculator(5, 6);
NS_LOG_UNCOND(result);
}
int add(int a, int b)
{
return a + b;
}
int
main (int argc, char *argv[])
{
A one(MakeCallback(&add));
one.calculate();
}
方法的回调(MemPtrCallbackImpl)
- 定义回调:
Callback<Complex, Complex &> m_complexCalculator;
- 创建回调对象:
Complex first(1, 3);
Callback<Complex, Complex &> callback = MakeCallback(&Complex::add, &first);
完整程序
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
#include <iostream>
#include "ns3/core-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TryCallback");
class Complex {
public:
Complex(int a, int b);
Complex add(Complex & another);
friend std::ostream & operator <<(std::ostream & out, Complex & c);
private:
int m_a;
int m_b;
};
Complex::Complex (int a, int b)
{
m_a = a;
m_b = b;
}
Complex Complex::add (Complex & another)
{
int a = m_a + another.m_a;
int b = m_b + another.m_b;
return Complex(a, b);
}
std::ostream & operator <<(std::ostream & out, Complex & c) {
out << c.m_a << " + " << c.m_b << "i";
return out;
}
class A {
public:
A(Callback<int, int, int> calculator);
A(Callback<Complex, Complex &> complexCalculator);
void calculate();
void complexCalculate(Complex b);
private:
Callback<int, int, int> m_calculator;
Callback<Complex, Complex &> m_complexCalculator;
};
A::A (Callback<int, int, int> calculator)
{
m_calculator = calculator;
}
A::A (Callback<Complex, Complex &> complexCalculator)
{
m_complexCalculator = complexCalculator;
}
void
A::complexCalculate (Complex b)
{
Complex result = m_complexCalculator(b);
std::cout << result << std::endl;
}
void
A::calculate ()
{
int result = m_calculator(5, 6);
NS_LOG_UNCOND(result);
}
int add(int a, int b)
{
return a + b;
}
int multiply(int a, int b)
{
return a * b;
}
int
main (int argc, char *argv[])
{
Complex first(1, 3);
Complex second(2, 5);
A one(MakeCallback(&Complex::add, &first));
one.complexCalculate(second);//3+8i
}
绑定参数的回调(MakeBoundCallback)
对于对象的方法,由于对象本身就具有存储数据的能力,就无需绑定参数的回调这个概念。因此,NS-3当中并未提供绑定参数的对象方法的回调。
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
#include <iostream>
#include "ns3/core-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TryCallback");
class A {
public:
A(Callback<int, int> calculator);
void calculate();
private:
Callback<int, int> m_calculator;
};
A::A (Callback<int, int> calculator)
{
m_calculator = calculator;
}
void
A::calculate ()
{
int result = m_calculator(6);
NS_LOG_UNCOND(result);
}
int add(int a, int b)
{
return a + b;
}
int multiply(int a, int b)
{
return a * b;
}
int
main (int argc, char *argv[])
{
A one(MakeBoundCallback(&add, 8));
one.calculate();
}
判断回调是否绑定函数(Callback::IsNull())
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
#include <iostream>
#include "ns3/core-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TryCallback");
class A {
public:
A();
A(Callback<int, int, int> calculator);
void calculate();
void
setCalculator (const Callback<int, int, int>& calculator)
{
m_calculator = calculator;
}
private:
Callback<int, int, int> m_calculator;
};
A::A(){}
A::A (Callback<int, int, int> calculator)
{
m_calculator = calculator;
}
void
A::calculate ()
{
if(m_calculator.IsNull()) {
NS_LOG_UNCOND("callback is not bind to any function.");
} else {
int result = m_calculator(6, 8);
NS_LOG_UNCOND(result);
}
}
int add(int a, int b)
{
return a + b;
}
int multiply(int a, int b)
{
return a * b;
}
int
main (int argc, char *argv[])
{
A one(MakeCallback(&add));
one.calculate();
one.setCalculator(MakeNullCallback<int, int, int>()); //构造空回调
one.calculate();
}
回调作为属性(CallbackValue)
程序演示:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
#include <iostream>
#include "ns3/core-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TryCallback");
namespace ns3 {
class A : public Object{
public:
static TypeId GetTypeId (void);
A();
void calculate();
void
setCalculator (const Callback<int, int, int>& calculator)
{
m_calculator = calculator;
}
private:
Callback<int, int, int> m_calculator;
};
A::A(){}
TypeId
A::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::A")
.AddConstructor<A> ()
.SetParent<Object> ()
.AddAttribute ("calculator", "help text",
CallbackValue (),
MakeCallbackAccessor (&A::m_calculator),
MakeCallbackChecker ())
;
return tid;
}
void
A::calculate ()
{
if(m_calculator.IsNull()) {
NS_LOG_UNCOND("callback is bind to any function.");
} else {
int result = m_calculator(6, 8);
NS_LOG_UNCOND(result);
}
}
int add(int a, int b)
{
return a + b;
}
int multiply(int a, int b)
{
return a * b;
}
}
int
main (int argc, char *argv[])
{
Ptr<A> a = CreateObject<A>();//使用智能指针创建一个A类的实例
a->SetAttribute("calculator", CallbackValue(MakeCallback(&add)));//为属性calculator指定一个回调函数add
a->calculate();
}
例子中将之前A当中的有参构造函数删除,此时向A当中指定回调的任务现在由属性框架来完成。因此A必须继承Object类,并且实现GetTypeId()方法来使用属性框架。在GetTypeId()方法中,创建了一个属性叫做”calculator”,其绑定到了成员变量m_calculator上,属性值类型为CallbackValue。该属性默认回调值为空,使用了变量访问器和默认检查器。