fa. 的回答是一个好的开始。但是,它并不能解决拥有多个相同类型所有者的问题。一种解决方案是让通知程序存储所有者列表而不是单个所有者。这是一个快速实现,以展示这个想法:
template <typename Owner, typename Owned>
class Notifier
{
protected:
Notifier()
{}
// Constructor taking a single owner
Notifier(Owner & o)
{
owners.push_back(&o);
}
// Constructor taking a range of owners
template <typename InputIterator>
Notifier(InputIterator firstOwner, InputIterator lastOwner)
: owners(firstOwner, lastOwner) {}
~Notifier()
{
OwnerList::const_iterator it = owners.begin();
OwnerList::const_iterator end = owners.end();
for ( ; it != end ; ++it)
{
(*it)->notify(static_cast<Owned*>(this));
}
}
// Method for adding a new owner
void addOwner(Owner & o)
{
owners.push_back(&o);
}
private:
typedef std::vector<Owner *> OwnerList;
OwnerList owners;
};
你可以这样使用它:
class Owner;
class Owned : public Notifier<Owner, Owned>
{
typedef Notifier<Owner, Owned> base;
//Some possible constructors:
Owned(Owner & o) : base(o) { }
Owned(Owner & o1, Owner & o2)
{
base::addOwner(o1); //qualified call of base::addOwner
base::addOwner(o2); //in case there are other bases
}
Owned(std::list<Owner*> lo) : base(lo.begin(), lo.end()) { }
};
如果您有许多不同类型的所有者,则此解决方案可能会变得相当难以使用。在这种情况下,您可能需要查看 boost 元编程库(MPL、Fusion),您最终可以得到一个代码,让您可以执行以下操作:
class Owned : public Notifier<Owned, OwnerType1, OwnerType1, OwnerType2>
{
Owned(OwnerType1 & o1, OwnerType1 & o2, OwnerType2 & o3)
: base(o1,o2,o3)
};
但是,实施此解决方案将比以前的解决方案长一点。