集合(Set),映射表(MAP)

集合(Set)

集合容器的特性是不允许又重复的元素序列,即每个对象元素在集合中保证是唯一的。ACE提供了两种类型的集合容器:有界集合(ACE_Bounded_Set)和无界集合(ACE_Unbounded_Set),顾名思义有界集合的大小是固定的,而无界集合的大小是动态调整的。基于集合元素唯一的特性,集合容器在插入对象元素的时候要通过'=='操作符堆元素进行相等比较。所以必要的时候你需要重载operator==()操作符。

代码示例

此示例演示了ACE_Bounded_SetACE_Unbounded_Set的使用方法,包括集合元素的插入查找,迭代等。

Sets.cpp

// Sets.cpp,v 1.3 2004/01/05 22:57:06 shuston Exp
 
#include "ace/OS_Memory.h"
#include "ace/Log_Msg.h"
#include "ace/Containers.h"
#include "DataElement.h"
 
class SetExample
{
public:
  // Illustrate all ACE set types.
  int run (void);
 
private:
  // Illustrate the ACE Bounded Sets.
  int runBoundedSet (void);
 
  // Illustrate the ACE Unbounded sets.
  int runUnboundedSet (void);
};
 
int SetExample::run (void)
{
  ACE_TRACE (ACE_TEXT ("SetExample::run"));
 
  ACE_ASSERT (!this->runBoundedSet ());
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("/n# of live objects %d/n"),
              DataElement::numOfActiveObjects ()));
 
  ACE_ASSERT (!this->runUnboundedSet ());
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("/n# of live objects %d/n"),
              DataElement::numOfActiveObjects ()));
 
  return 0;
}
// Listing 1 code/ch05
int SetExample::runBoundedSet ()
{
  ACE_TRACE (ACE_TEXT ("SetExample::runBoundedSet"));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using a bounded set/n")));
  ACE_Bounded_Set<DataElement> bset (100);
 
  DataElement elem[100];
  for (int i = 0; i < 100; i++)
    {
      elem[i].setData (i);
 
      // Inserting two copies of the same element isn't allowed.
      bset.insert (elem[i]);
      if (bset.insert (elem[i]) == -1)
        {
          ACE_DEBUG ((LM_ERROR, ACE_TEXT ("%p/n"),
                      ACE_TEXT ("insert set")));
        }
    }
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d/n"),
              DataElement::numOfActiveObjects ()));
 
  DataElement elem1 (10), elem2 (99);
  if (!bset.find (elem1) && !bset.find (elem2))
    {
      ACE_DEBUG ((LM_INFO,
                  ACE_TEXT ("The elements %d and %d are ")
                  ACE_TEXT ("in the set!/n"),
                  elem1.getData (), elem2.getData ()));
    }
 
  for (int j = 0; j < 50; j++)
    {
      bset.remove (elem[j]);  // Remove the element from the set.
      ACE_DEBUG
        ((LM_DEBUG, ACE_TEXT ("%d:"), elem[j].getData ()));
    }
 
  if ((bset.find (elem[0]) == -1) && (bset.find (elem[49]) == -1))
    {
      ACE_DEBUG ((LM_INFO,
                  ACE_TEXT ("The elements %d and %d are ")
                  ACE_TEXT ("NOT in the set!/n"),
                  elem[0].getData (), elem[99].getData ()));
    }
 
  return 0;
}
// Listing 1
// Listing 2 code/ch05
int SetExample::runUnboundedSet ()
{
  ACE_TRACE (ACE_TEXT ("SetExample::runUnboundedSet"));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using an unbounded set./n")));
  ACE_Unbounded_Set<DataElement*> uset;
  for (int m = 0; m < 100; m++)
    {
      DataElement *elem;
      ACE_NEW_RETURN (elem, DataElement (m), -1);
      uset.insert (elem);
    }
  DataElement deBegin (0), deEnd (99);
  if (!uset.find (&deBegin) && !uset.find (&deEnd))
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Found the elements/n")));
    }
 
  // Iterate and destroy the elements in the set.
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Deleting the elements/n")));
  ACE_Unbounded_Set_Iterator<DataElement*> iter (uset);
  for (iter = uset.begin (); iter != uset.end (); iter++)
    {
      DataElement* elem = (*iter);
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem->getData ()));
      delete elem;
    }
 
  return 0;
}
// Listing 2
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  SetExample se;
  se.run ();
  return 0;
}
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class ACE_Unbounded_Set<DataElement*>;
template class ACE_Unbounded_Set_Iterator<DataElement*>;
template class ACE_Bounded_Set<DataElement>;
template class ACE_Node<DataElement*>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_Unbounded_Set<DataElement*>
#pragma instantitate ACE_Unbounded_Set_Iterator<DataElement*>
#pragma instantiate ACE_Bounded_Set<DataElement>
#pragma instantiate ACE_Node<DataElement*>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION*/

映射表(MAP)

ACE通过ACE_Map_Manager类模板实现键到值的映射,容器是一个动态的条目数组,每个条目有一个键/值对组成。ACE_Map_Manager要求键对象是可比较的,可以通过重载键元素的operator==(),或针对键对象对ACE_Map_Manager::equal()方法进行特化。

示例代码

KeyType.h

KeyType类完成了示例代码中使用的键对象的简单定义,按照ACE_Map_Manager的规范重载了operator==()
/* -*- C++ -*- */
// KeyType.h,v 1.1 2004/01/01 21:01:00 shuston Exp
 
#ifndef __KEYTYPE_H_
#define __KEYTYPE_H_
 
// Listing 1 code/ch05
class KeyType
{
public:
  friend bool operator == (const KeyType&, const KeyType&);
 
  KeyType () : val_(0) {}
  //用于自动类型转换:构造函数转换
  KeyType (int i) : val_(i) {}
  KeyType (const KeyType& kt) { this->val_ = kt.val_; };
  //用于自动类型转换:运算符转换
  operator int() const { return val_; };
 
private:
  int val_;
};
 
bool operator == (const KeyType& a, const KeyType& b)
{
  return (a.val_ == b.val_);
}
// Listing 1
 
#endif /* __KEYTYPE_H_ */
 

Map_Manager.cpp

此示例演示了ACE_Map_Manager的使用方法,包括数据元素的插入、查找、正向遍历(迭代)、反向遍历。
// Map_Manager.cpp,v 1.2 2005/12/22 11:29:35 shuston Exp
 
#include "ace/Log_Msg.h"
#include "ace/Map_Manager.h"
#include "ace/Synch.h"
#include "DataElement.h"
#include "KeyType.h"
 
class Map_Example
{
public:
  // Illustrate the ACE_Map_Manager.
  int run (void);
 
private:
  // Iterate in the forward direction.
  void iterate_forward (void);
 
  // Iterate in the other direction.
  void iterate_reverse (void);
 
  // Remove all elements from the map.
  void remove_all (void);
 
private:
  //模板提供了三个参数 键对象、数据元素对象、同步锁类型
  //如果你希望对映射表的操作是线程安全的应该用ACE_Thread_Mutex代替ACE_Null_Mutex
  ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex> map_;
};
 
// Listing 2 code/ch05
int Map_Example::run (void)
{
  ACE_TRACE (ACE_TEXT ("Map_Example::run"));
 
  // Corresponding KeyType objects are created on the fly.
  for (int i = 0; i < 100; i++)
    {
      map_.bind (i, DataElement (i));
    }
 
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Map has /n")));
  for (int j = 0; j < 100; j++)
    {
      DataElement d;
      map_.find (j,d);
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), d.getData ()));
    }
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("/n")));
 
  // Iterate in the forward direction.
  this->iterate_forward ();
 
  // Iterate in the other direction.
  this->iterate_reverse ();
 
  // Remove all elements from the map.
  this->remove_all ();
 
  // Iterate in the forward direction.
  this->iterate_forward ();
 
  return 0;
}
// Listing 2
// Listing 3 code/ch05
void Map_Example::iterate_forward (void)
{
  ACE_TRACE (ACE_TEXT ("Map_Example::iterate_forward"));
 
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Forward iteration/n")));
  for (ACE_Map_Manager<KeyType,
                       DataElement,
                       ACE_Null_Mutex>::iterator
       iter = map_.begin ();
       iter != map_.end ();
       iter++)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"),
                  (*iter).int_id_.getData ()));
    }
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("/n")));
}
 
 
void Map_Example::iterate_reverse (void)
{
  ACE_TRACE (ACE_TEXT ("Map_Example::iterate_reverse"));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reverse iteration/n")));
  for (ACE_Map_Manager<KeyType,
                       DataElement,
                       ACE_Null_Mutex>::reverse_iterator
       iter = map_.rbegin ();
       iter != map_.end ();
       iter++)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"),
                  (*iter).int_id_.getData ()));
    }
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("/n")));
}
// Listing 3
// Listing 4 code/ch05
void Map_Example::remove_all (void)
{
  ACE_TRACE (ACE_TEXT ("Map_Example::remove_all"));
 
  // Note that we can't use the iterators here as they
  // are invalidated after deletions or insertions.
  map_.unbind_all ();
}
// Listing 4
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  Map_Example me;
  return  me.run ();
}
 
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex>
;
template class ACE_Map_Iterator<KeyType,DataElement,ACE_Null_Mutex>
;
template class ACE_Map_Entry<KeyType,DataElement>
;
template class ACE_Map_Iterator_Base<KeyType,DataElement,ACE_Null_Mutex>
;
template class ACE_Map_Reverse_Iterator<KeyType,DataElement,ACE_Null_Mutex>
;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_Map_Manager<KeyType,DataElement,ACE_Null_Mutex>
#pragma instantiate ACE_Map_Iterator<KeyType,DataElement,ACE_Null_Mutex>
#pragma instantiate ACE_Map_Reverse_Iterator<KeyType,DataElement,ACE_Null_Mutex>
#pragma instantiate ACE_Map_Entry<KeyType,DataElement>
#pragma instantiate ACE_Map_Iterator_Base<KeyType,DataElement,ACE_Null_Mutex>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
 
 

执行结果

D:/project/ACE_wrappers/examples/APG/Containers>Map_Manager
Map has
0:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:
30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56
:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:8
3:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:
Forward iteration
99:98:97:96:95:94:93:92:91:90:89:88:87:86:85:84:83:82:81:80:79:78:77:76:75:74:73
:72:71:70:69:68:67:66:65:64:63:62:61:60:59:58:57:56:55:54:53:52:51:50:49:48:47:4
6:45:44:43:42:41:40:39:38:37:36:35:34:33:32:31:30:29:28:27:26:25:24:23:22:21:20:
19:18:17:16:15:14:13:12:11:10:9:8:7:6:5:4:3:2:1:0:
Reverse iteration
0:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:
30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56
:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:8
3:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99:
Forward iteration

你可能感兴趣的:(集合(Set),映射表(MAP))