sud salvacion registros rama que progreso patriarcal obra misional miembros lider ipm formulario consejo bendicion barrio c++ inheritance operator-overloading new-operator

c++ - salvacion - ¿Son las sobrecargas de miembros nuevos/eliminados en una clase derivada alguna vez útiles?



que es el ipm sud (4)

¿Existe un escenario del mundo real en el que una clase derivada utiliza un asignador diferente de su base y se basa en un destructor virtual para encontrar el operator delete miembro correcto operator delete ?

No estoy seguro de lo que consideraría un escenario del mundo real, pero el ejemplo obvio que me viene a la mente es una jerarquía de herencia que está arraigada en una clase base abstracta, con clases derivadas muy diferentes (en tamaño), muchas de las cuales son creado y destruido regularmente, mientras que se requiere velocidad para esas asignaciones / desasignaciones.

Es posible que desee asignadores personalizados para esas clases derivadas, porque los asignadores para blobs de memoria de un tamaño específico pueden ser muy rápidos, y es posible que desee usar asignadores diferentes para cada clase derivada, porque sus tamaños son muy diferentes.

Sin embargo, no puedo darles un ejemplo concreto de esto, porque a lo largo de los años he encontrado que evitar la asignación / desasignación es mucho mejor que acelerarlo, por lo que en casi veinte años casi nunca he sobrecargado new clases específicas. delete (Por supuesto, como generalmente cuando hablamos de optimización sofisticada, aparece "juegos", por lo que podemos imaginar un juego que necesita crear y destruir grandes cantidades de entidades muy diferentes).

Solo estaba respondiendo una pregunta sobre la falta de eliminación de ubicación correspondiente a la ubicación nueva. El motivo parece ser la forma en operator delete se llama a la operator delete según el tipo dinámico del objeto (correspondiente al tipo utilizado para encontrar el operator new ).

La colocación new ha sido útil. Cuando se trata de la asignación personalizada, probablemente hay una clase reutilizable en la que diferentes instancias administran diferentes grupos. Los singletons son un anti-patrón y todo eso.

Puedo entender la conveniencia de hacer new thing; trabaje sin realizar un seguimiento de un asignador, pero hacer cosas para diferentes ramas de la jerarquía de tipos parece bastante complicado.

¿Existe un escenario del mundo real en el que una clase derivada utiliza un asignador diferente de su base y se basa en un destructor virtual para encontrar el operator delete miembro correcto operator delete ?

Para que esto no sea subjetivo, aceptaré la respuesta que sea más plausible. No discutamos sobre los olores de código o la "mejor" forma de hacer las cosas.


De hecho, he usado esto en el pasado! Es útil para arquitecturas de memoria no uniformes: plataformas con áreas de memoria muy rápidas muy pequeñas sin un sistema operativo, etc.

Específicamente, imagine, por ejemplo, un chip ARM con una pequeña cantidad de TCM (memoria estrechamente acoplada; esencialmente, SRAM incrustada en el SoC, por ejemplo, con un tiempo de acceso de 1 ciclo).

Luego, usamos los resultados del generador de perfiles muy tarde en el desarrollo del producto, justo antes del envío (imagine que se trata de un cartucho para un popular sistema de juegos de mano, por ejemplo) para determinar que ciertas clases se beneficiarían de esta SRAM más rápida.

Un operator new miembro simple que aproveche este TCM solo para las clases derivadas ahora puede tener sentido: no podemos permitirnos tener toda la jerarquía de clases utilizando esta SRAM, sino para ciertas clases derivadas con un bajo nivel de instanciación pero muy utilizadas. Se convierte en una optimización simple y efectiva. Hemos recuperado 2% -10% o más del tiempo de fotogramas en algunos casos redireccionando ciertas asignaciones de esta manera.


En realidad, nunca he usado sobrecargas nuevas / eliminadas en una clase derivada o alguna vez he pensado en ello, pero esta pregunta fue interesante y decidí investigar un poco y darle una oportunidad. He encontrado un par de referencias adecuadas:

ARM http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka14267.html

Esta referencia en realidad tiene un código de ejemplo de una clase derivada que sobrecarga a su clase base sobrecargada nueva.

Universidad de Vanderbilt http://www.vuse.vanderbilt.edu/~adamsja/Courses/CS251/Projects/4/memPool.pdf

Esta referencia no proporciona ningún material explícito sobre la sobrecarga de nuevos en una clase derivada, sin embargo, menciona algunas razones interesantes como por qué sobrecargar de nuevo. Esos motivos incluyen:

  • Para compensar la alineación subóptima en el asignador predeterminado
  • Para agrupar objetos relacionados uno cerca del otro
  • Para obtener un comportamiento poco convencional, como sobrescribir la memoria con ceros para aumentar la seguridad de los datos de la aplicación

Ahora, en base a esas dos referencias, he decidido que podría haber algunas razones para sobrecargar new / delete en una clase derivada. Mis razones se alinean básicamente con las razones que enumeré en la presentación de VU, pero también parecen ser relevantes en función de la referencia ARM que implica para mí un escenario integrado o especializado.

  • Los sistemas integrados a menudo son muy personalizados en el nivel de hardware, sin embargo, son comunes en un sentido estandarizado en el nivel de software. Podría ver una situación en la que, dependiendo de una configuración de configuración / correa de hardware, se elige un determinado tipo de objeto en el tiempo de ejecución (clase derivada) porque necesita asignar memoria de una manera específica o ubicación específica.
  • La agrupación parece plausible porque podría imaginar un escenario en el que algunos objetos se tratan de la misma manera en un "flujo de trabajo" de alto nivel, pero cuando se procesan, los diferentes tipos de esos objetos se manejan de manera muy diferente. Podría ser beneficioso ubicar tipos específicos de objetos cercanos entre sí para tareas que requieren un proceso intenso (es decir, buscar, clasificar, priorizar, etc.).
  • El último punto es interesante porque podría ver ciertos casos en los que la asignación depende de la clasificación de seguridad de la información que se almacena.

Nuevamente, nunca he encontrado una razón o implementado algo como usted ha mencionado, pero estos son mis pensamientos con una pequeña investigación.


Un operator new miembro operator new / delete puede ser útil para eliminar la asignación personalizada no deseada de una clase base, por ejemplo, si la base no estaba destinada a extenderse. Pero la base necesitaría un destructor virtual, o el objeto base nunca debe ser objeto de delete .

En realidad, el envío del destructor virtual de la operator delete del operator delete se requiere independientemente de la sobrecarga. La característica probablemente existe para admitir la herencia múltiple, y encontrar dinámicamente la operator delete miembro correcto es solo un efecto secundario.

La regla es simplemente que un destructor virtual para un objeto más derivado llama al operator delete . El motivo principal es pasar el puntero y el tamaño más derivados. Que el contexto también permita que el programa encuentre dinámicamente la función de desasignación correcta es solo un feliz efecto secundario.

Por lo tanto, puede que haya o no una aplicación útil para el envío de delete dinámica, pero no existe un mecanismo específico para que funcione.

Demo simple :

struct pad { int x; virtual ~pad() {} }; struct b { int x; }; struct vb { int x; virtual ~vb() {} }; struct d : pad, b, vb {}; void operator delete( void *p ) { std::cout << "free " << p << ''/n''; } int main() { std::cout << "With virtual destructor:/n"; d *p = new d; std::cout << "allocate " << p << ", delete " << static_cast< vb * >( p ) << ''/n''; delete static_cast< vb * >( p ); std::cout << "With plain destructor:/n"; p = new d; std::cout << "allocate " << p << ", delete " << static_cast< b * >( p ) << ''/n''; delete static_cast< b * >( p ); }