fa.'s answer è un buon inizio. Tuttavia, non risolve il problema di avere più proprietari dello stesso tipo. Una soluzione è quella di far memorizzare al notificatore un elenco di proprietari anziché uno singolo. Ecco una rapida implementazione, per mostrare l'idea:
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;
};
Si può usare in questo modo:
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()) { }
};
Nel caso in cui si hanno molti diversi tipi di proprietari, questa soluzione può diventare piuttosto difficile usare. In questo caso, si potrebbe desiderare di guardare le librerie spinta metaprogrammazione (MPL, Fusion), con il quale si potrebbe finire con un codice che consentono di fare gli animali del genere:
class Owned : public Notifier<Owned, OwnerType1, OwnerType1, OwnerType2>
{
Owned(OwnerType1 & o1, OwnerType1 & o2, OwnerType2 & o3)
: base(o1,o2,o3)
};
Tuttavia, l'implementazione di questa soluzione sarebbe essere un po 'più lungo del precedente
fonte
2009-04-02 15:35:48
È necessario il polimorfismo statico oppure è possibile creare un IOwner di classe di base astratto con ad es. un metodo virtuale puro 'notifica'? –
No, non posso avere una "notifica" virtuale pura. –