hay algunos buenos argumentos para contra const, aquí, así que aquí está mi opinión: -
Personalmente, no tendríamos estos "OnXXXUpdated" como parte de mis clases de administrador. Creo que esta es la razón por la cual hay cierta confusión en cuanto a las mejores prácticas. Está notificando a las partes interesadas sobre algo y no sabe si el estado del objeto cambiará o no durante el proceso de notificación. Puede, o no puede. Lo que es obvio para mí, es que el proceso de notificación a las partes interesadas debe ser un const.
Por lo tanto, para resolver este dilema, esto es lo que haría:
deshacerse de las funciones OnXXXXUpdated de sus clases de administrador.
Escribe un Administrador de notificaciones, aquí hay un prototipo, con los siguientes supuestos:
"Args" es una clase base arbitraria para pasar información cuando las notificaciones suceden
"Delegado" es una especie de un puntero de función (p. ej. FastDelegate).
class Args
{
};
class NotificationManager
{
private:
class NotifyEntry
{
private:
std::list<Delegate> m_Delegates;
public:
NotifyEntry(){};
void raise(const Args& _args) const
{
for(std::list<Delegate>::const_iterator cit(m_Delegates.begin());
cit != m_Delegates.end();
++cit)
(*cit)(_args);
};
NotifyEntry& operator += (Delegate _delegate) {m_Delegates.push_back(_delegate); return(*this); };
}; // eo class NotifyEntry
std::map<std::string, NotifyEntry*> m_Entries;
public:
// ctor, dtor, etc....
// methods
void register(const std::string& _name); // register a notification ...
void unRegister(const std::string& _name); // unregister it ...
// Notify interested parties
void notify(const std::string& _name, const Args& _args) const
{
std::map<std::string, NotifyEntry*>::const_iterator cit = m_Entries.find(_name);
if(cit != m_Entries.end())
cit.second->raise(_args);
}; // eo notify
// Tell the manager we're interested in an event
void listenFor(const std::string& _name, Delegate _delegate)
{
std::map<std::string, NotifyEntry*>::const_iterator cit = m_Entries.find(_name);
if(cit != m_Entries.end())
(*cit.second) += _delegate;
}; // eo listenFor
}; // eo class NotifyManager
he dejado algo de código como usted puede decir probablemente, pero usted consigue la idea. Me imagino que este Administrador de notificaciones sería un singleton. Ahora, asegurando que el Administrador de notificaciones se crea desde el principio, el resto de sus gerentes simplemente registrar sus notificaciones en su constructor de la siguiente manera:
MyManager::MyManager()
{
NotificationMananger.getSingleton().register("OnABCUpdated");
NotificationMananger.getSingleton().register("OnXYZUpdated");
};
AnotherManager::AnotherManager()
{
NotificationManager.getSingleton().register("TheFoxIsInTheHenHouse");
};
Ahora, cuando el gerente tiene que notificar a las partes interesadas, simplemente llamadas notificar:
MyManager::someFunction()
{
CustomArgs args; // custom arguments derived from Args
NotificationManager::getSingleton().notify("OnABCUpdated", args);
};
Otras clases pueden escuchar esto.
Me he dado cuenta de que acabo de tipear el patrón Observer, pero mi intención era mostrar que el problema está en cómo se plantean estas cosas y si están en estado const o no. Al abstraer el proceso de notificación de la clase mananager, los destinatarios de la notificación son libres de modificar esa clase de administrador. Simplemente no el administrador de notificaciones. Creo que esto es justo.
Además, tener un solo lugar para levantar notificaciones es una buena práctica, ya que le da un lugar único donde puede rastrear sus notificaciones.
Supongo que usted está argumentando a favor de declarar el método const? – starblue
Si esto surgiera en una revisión del código, probablemente no me habría opuesto de ninguna manera a menos que hubiera algún otro factor en juego. Si todos acceden a lo global y no hay referencias, todo eso no importa. Estoy totalmente en desacuerdo con la premisa de que el análisis estático puede indicarle si este método debe ser const: El análisis estático le dice que * podría * ser const * tal como se implementó *, pero no sabe si tiene la intención de mejorar la función más tarde (p. Ej. con estadísticas, o puesta en cola de mensajes o eliminación de duplicados o lo que sea). –