set 容器与 map 非常类似。区别在于,集合不存储键/值对,在 set 中,值本身就是键。如果要存储没有显示键的信息,但是又希望对元素以便快速插入、查找和删除,此时 set 就很有用。
set 提供的接口与 map 的接口几乎相同。主要区别是 set 没有提供 operator [ ]。另外,尽管标准中没有明确指出来,但是大多数实现指令都令 set iterator 等同于 const_iteraotr,因此不能通过 iterator 来修改 set 的元素。即使你的 STL 版本允许通过一个 iterator 修改 set 元素,也要避免这样做,因为修改 set 中的元素(仍在容器中)会破坏有序顺序。
集合示例:访问控制列表
在计算机系统上实现基本安全的一种做法是通过访问控制列表。系统上的每一个实体(如一个文件或一个设备)都有相应的允许访问该实体的用户列表。用户一般只能由有特殊权限的用户从一个实体的许可列表中增加和删除用户。在内部,set 容器提供了一个很不错的方法来表示访问控制列表。可以对应每个实体有一个 set ,其中包括允许 访问该实体的所有用户名。下面是一个简单的访问控制列表的类定义。
#include<set> #include<string> #include<list> using std::set; using std::string; using std::list; class AccessList { public: AccessList(){} //adds the user to the permission list void addUser(const string& user); //remove the user from the permission list void removeUser(const string& user); //returns true if user is in the permission list bool isAllowed(const string& user) const; //returns a list of all the users who have permissions list<string> getAllUsers() const; protected: set<string> mAllowed; }
#include "AccessList.h" using namespace std; void AccessList::addUser(const string& user) { mAllowed.insert(user); } void AccessList::removeUser(const string& user) { mAllowed.erase(user); } bool AccessList::isAllowed(const string& user) const { return (mAllowed.count(user)==1); } list<string> AccessList::getAllUsers() const { list<string> users; users.insert(users.end(),mAllowed.begin(),mAllowed.end()); return (users); }
#include "AccessList.h" #include<iostream> #include<iterator> using namespace std; int main() { AccessList fileX; fileX.addUser("nsolter"); fileX.addUser("klep"); fileX.addUser("baduser"); fileX.removeUser("baduser"); if(fileX.isAllowed("nsolter")) { cout<<"nsolter has permission!"<<endl; } if(fileX.isAllowed("baduser")) { cout<<"baduser has permission!"<<endl; } list<string> users = fileX.getAllUsers(); for(list<string>::const_iterator it = users.begin(); it !=users.end(); ++it) { cout<<*it<<" "; } cout << endl; return 0; }