C语言C++ - 邂逅对象

C的++

本文为那些年大家追过的言语之C++篇。C语言的命名来源于其参考的B语言.
而C++的命名, 正因为全数C的考虑和法则主导都被封存下去,
并且引入了类的概念, 以及包装, 继承, 多态的思想. 关键是观念的转变.
系统学习, 推荐 C++
Primer

.

黑魔法

1. 模板 (Template)

固然如此类是C++与C最直观的界别形式, 但本文并不打算在其开支笔墨. 相较类,
多态的表征更抓住本身. 模板是一种对项目进行参数化的工具, 平常有两种样式:
针对参数类型不相同的函数模板, 以及针对性属性和操作类型不一样的类模板.
使用模板可以为类或函数评释构造一种通用格局,
使类中或多或少成员要么函数的参数及再次来到值类型任意。深远学习请阅读 C++
Templates

.

2. 标准模板库 (STL)

STL (Standard Template Library) 的大旨部件包蕴: 容器 (Container), 算法
(Algorithms), 迭代器 (Iterator). 简单的话, 它们分别表示结构, 操作, 指针.
STL的三个最主要特征是它不是面向对象的. 它依照模板而不是OOP中的封装, 继承,
多态. 关于STL的始末请参见学习:

在C++ STL中, 很多片段 (set, multiset, map, multimap)
应用了红黑树的变体.
红黑树操作具有得天独厚的最坏情况复杂度, 在实践中, 它可以展开O(log
nC语言,)
日子内的搜寻,插入和删除等操作.
红黑树是各样节点都包罗稻草黄或品绿的二叉平衡查找树.
具有如下性质:

  1. 节点是革命或草绿.
  2. 根节点是青莲.
  3. 每一种叶节点 (NIL节点) 是土黄.
  4. 种种青蓝节点的多个子节点都以浅紫蓝,
    从每种叶子到根的兼具路线上不能有七个两次三番的革命节点.
  5. 从任一节点到其每一个叶子的具有途径都包涵相同数量的浅淡紫灰节点.

那些性质明确了红黑树的关键天性:
从根到叶子的最长只怕路径不多于最短可能路径的两倍长.
其好处是既维持了树的争论平衡, 又比AVL的插入删除操作的纷纭低许多.
红黑树的插入及删除操作会破坏性质, 因而须求通过旋转来维护.
直观领悟珍惜操作请看红黑树从头至尾插入和删除结点的全程演示图.
该文作者所写的红黑树专题那么些逼真,
值得研读.

3. 回调 (Callback)

更准确的说, 回调是C的性质.
第四回接触回调函数是在ns-3中,
其功能是让某函数以函数指针的样式变为有些类的性质,
以供该类在方便的时候调用该函数.
引用ns-3的Tutorial中的讲解:

The goal of the Callback system in ns-3 is to allow one piece of code
to call a function (or method in C++) without any specific
inter-module dependency. This ultimately means you need some kind of
indirection – you treat the address of the called function as a
variable. This variable is called a pointer-to-function variable.

举个ns-3中蒙受的有关wifi中mac层收包的例子, 为保险原汁原味,
代码中有些与回调毫不相关的始末从未删去:

class MacRxMiddle{
  typedef Callback<void, Ptr<Packet>, const WifiMacHeader*> ForwardUpCallback;
  ForwardUpCallback m_callback;
  void SetForwardCallback (ForwardUpCallback callback);
  void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
  ...
};

void MacRxMiddle::SetForwardCallback (ForwardUpCallback callback){
  m_callback = callback;
}

void MacRxMiddle::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr){
  NS_LOG_FUNCTION (packet << hdr);
  NS_ASSERT (hdr->IsData () || hdr->IsMgt ());
  OriginatorRxStatus *originator = Lookup (hdr);
  if (!(SequenceNumber16 (originator->GetLastSequenceControl ()) < SequenceNumber16 (hdr->GetSequenceControl ()))) NS_LOG_DEBUG ("Sequence numbers have looped back. last recorded=" << originator->GetLastSequenceControl () << " currently seen=" << hdr->GetSequenceControl ());
  if(IsDuplicate (hdr, originator))
    NS_LOG_DEBUG ("duplicate from=" << hdr->GetAddr2 () <<", seq=" << hdr->GetSequenceNumber () <<", frag=" << hdr->GetFragmentNumber ());
    return;
  }
  Ptr<Packet> agregate = HandleFragments (packet, hdr, originator);
  if (agregate == 0) return 0;
  if (!hdr->GetAddr1 ().IsGroup ()) originator->SetSequenceControl (hdr->GetSequenceControl ());
  m_callback (agregate, hdr);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class RegularWifiMac : public WifiMac{
  RegularWifiMac ();
  virtual void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
  MacRxMiddle *m_rxMiddle;
  ...
};

RegularWifiMac::RegularWifiMac (){
  m_rxMiddle->SetForwardCallback (MakeCallback (&RegularWifiMac::Receive, this));
  ...
}

void RegularWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr){
  NS_LOG_FUNCTION (this << packet << hdr);
  Mac48Address to = hdr->GetAddr1 ();
  Mac48Address from = hdr->GetAddr2 ();
  if (to != GetAddress ()) return;
  if (hdr->IsMgt () && hdr->IsAction ()){
    NS_ASSERT (m_qosSupported);
    WifiActionHeader actionHdr;
    packet->RemoveHeader (actionHdr);
    switch (actionHdr.GetCategory ()){
      case WifiActionHeader::BLOCK_ACK:
        ...
      default:
        NS_FATAL_ERROR ("Unsupported Action frame received");
        return;
      }
   }
  NS_FATAL_ERROR ("Don't know how to handle frame (type=" << hdr->GetType ());
}

那段代码中包括七个类MacENVISIONxMiddle和RegularWifiMac. 首先,
Mac翼虎xMiddle中有二个回调变量ForwardUpCallback m_callback;,
同时兼有七个操作, 用于设置m_callback的SetForwardCallback函数,
及用于拍卖收包行为的操作Receive函数. 并且,
Receive函数最终的讲话m_callback (agregate, hdr);,
是三个调用回调函数的语句. 然后, 分析类RegularWifiMac,
它富含二个MacLANDxMiddle类的实例化指针MacRxMiddle *m_rxMiddle;. 并且,
在开头化时,
通过m_rxMiddle->SetForwardCallback (MakeCallback (&RegularWifiMac::Receive, this));将RegularWifiMac::Receive函数关联刚刚提到的MacLX570xMiddle中的m_callback.
不难的话, 以上程序选取回调达到效果是,
Mac猎豹CS6xMiddle::Receive中的m_callback (agregate, hdr);可以轮换为RegularWifiMac::Receive (agregate, hdr);.
那么, 到底为何要使用回调函数,
而不是一向在MacLX570xMiddle中编辑RegularWifiMac::Receive函数呢?
因为RegularWifiMac类需求的是RegularWifiMac::Receive行为,
可是其他类中的MacLX570xMiddle实例, 要求的可能就是其它收包行为.
这便是回调的魔力.

结束语

就算new过那么多个object, 然则那并没有怎么…

C++