「ここで、別の種類の連絡先、Company (Contact から派生) を追加して、Composite パターンを実装する必要があります。これには、連絡先のコレクション (STL リストも) も含まれます。これは、「リーフ」タイプ (Friendsまたは知人)、または会社でもかまいません。」
Company の stl 互換の複合反復子を作成できます。
class Company : public Contact {
std::list<Contact *> contactList;
//snip...other private members
friend class CompanyIterator;
friend class ConstCompanyIterator;
public:
// nested iterator classes
class CompanyIterator : public std::iterator<std::forward_iterator_tag, Contact *> {
friend class Company;
// pair<>.first is the iterator obtain by calling begin()
// pair<>.second is the end iterator
std::stack< std::pair< std::list<Contact *>::iterator,
std::list<Contact *>::iterator> > iters_stack;
Contact *pCurrentContact;
Company *pCompany; // This is the top level company which will be iterated.
public:
explicit CompanyIterator(Company &c);
// Required forward iterator methods follow
CompanyIterator();
CompanyIterator(const CompanyIterator&);
CompanyIterator& operator=(const CompanyIterator& other);
Contact &operator*() const;
Contact *operator->() const;
CompanyIterator& operator++();
CompanyIterator operator++(int);
bool operator==(const CompanyIterator& x) const;
bool operator!=(const CompanyIterator& x) const;
};
// nested iterator class
class ConstCompanyIterator : public std::iterator<std::forward_iterator_tag,
const Contact *> {
friend class Company;
// We use CompanyIterator to implement ConstCompanyIteraor
CompanyIterator inner_iter; // fwd operations here,
// using "const_cast<Company *>(this)->method()"
public:
explicit ConstCompanyIterator(const Company & dir);
// This ctor will function as a cast operator, to convert a CompanyIterator
// into a ConstCompanyIterator
ConstCompanyIterator(const CompanyIterator &iter);
// Required forward iterator methods follow
ConstCompanyIterator();
ConstCompanyIterator(const ConstCompanyIterator&);
ConstCompanyIterator& operator=(const ConstCompanyIterator& other);
const Contact &operator*() const;
const Contact *operator->() const;
ConstCompanyIterator& operator++();
ConstCompanyIterator operator++(int);
bool operator==(const ConstCompanyIterator& x) const;
bool operator!=(const ConstCompanyIterator& x) const;
};
typedef CompanyIterator iterator;
typedef ConstCompanyIterator const_iterator;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
// snip... other Company public methods
};
上記の前方反復子メソッドの実装については、Github の複合反復子コードを参照してください。実装のほとんどは Directory.cpp にあります。github コードは、ファイル システムをモデル化する複合パターン用です。Class Directory はコンポジットです。クラス ファイルはリーフ クラスです。Class Node は基本コンポーネント クラスです。
find_if のファンクタは次のようになります
FindIfFunctor {
std::string name;
public:
FindIfFunctor(const std::string& n) : name(n) {}
bool operator()(const Contact& c) { return c.getName().compare(name); }
};
最後に、find_if コード
Company c;
// snip... stuff gets added to company
string someName("IBM");
find_if(c.begin(), c.end(), FindIfFunctor(someName));