2009-07-23 6 views
6

Me gustaría ejecutar algún código (tal vez una función) justo antes de cada llamada de función para una clase y todas las funciones de las clases que heredan de esa clase. Me gustaría hacer esto sin editar todas las funciones. ¿Es eso posible?Ejecutar código antes de cada llamada de función para una clase en C++

Me gustaría conformarme con tener una función llamada como la primera instrucción de cada llamada de función en lugar de llamarla justo antes.

Respuesta

8

AspectC++ es lo que quiere. No lo he usado, pero el paradigma Aspect-Oriented Programming intenta resolver este problema exacto.

+0

Estoy estrictamente en contra de los Aspectos, porque nunca se sabe cuánto costarán a su código y a qué código se expandirán. Tampoco está claro cómo depurar estos en C++, porque efectivamente producen código y pueden cambiar por completo los puntos de entrada de sus funciones. – ovanes

1

La manera poco conveniente de crear una clase contenedora que toma un objeto de su tipo base y llama a la función circundante y luego a la función que desea llamar. Esto sería algo así como decorator.

0

Esto suena como lo hace un generador de perfiles. ¿Has visto la fuente de alguna herramienta de creación de perfiles?

+0

Suena más como programación contractual. Verifica las condiciones previas y posteriores para validar que el contrato no se ha roto. –

3

Sugeriría utilizar el modismo Non Virtual Interface. Todas las funciones públicas no son virtuales. Todas las funciones virtuales están protegidas o son privadas. Los miembros públicos delegan las llamadas a miembros virtuales y generalmente se implementan como funciones en línea.

Esta es la forma en que IOStreams se implementan en STL. Puede leer más al respecto en C++ Wikibooks.

Propósito: modularizar/refactorizar los fragmentos de código comunes antes y después (por ejemplo, comprobación invariante, adquisición/liberación de bloqueos) para una jerarquía de clases completa en una ubicación.

Saludos,
Ovanes

1

Lo mejor que puede hacer es declarar un conjunto de funciones virtuales como protegidos y tienen los desarrolladores que heredan de la clase anulan las funciones virtuales. La interfaz utilizada por la clase base puede ser pública, que ejecuta el código deseado antes de pasar información al método virtual protegido.

Por ejemplo:

class Base { 
    public: 
    void MyMethod(void) { /* Insert code here */ YourMethod(); } 
    protected: 
    virtual void YourMethod(void) {} 
}; 

Si el desarrollador sabe que tiene una subclase específica, que todavía puede pasar por alto su código simplemente usando un moldeado dinámico, y usando su propio conjunto método. Como tal, es posible que desee seguir las otras sugerencias ya publicadas que no involucran el lenguaje base C++.

+0

Puedo pensar en otras formas que no impliquen invadir la clase que se prueba. –

2

Otra cosa que podría considerar es usar algo como el contenedor [boost/C++ 0X] shared_ptr, donde llama a su función personalizada en la sobrecarga '->' antes de devolver el puntero de instancia de clase. Implica modificar el uso pero no la clase subyacente, y lo he usado un par de veces para lograr el mismo efecto. Solo otro pensamiento.

+0

Esto suena como una excelente alternativa. – Greg

0

Usando g++, puede usar la opción -pg para las respectivas unidades de compilación, lo que hace que el compilador genere una llamada a la función mcount al inicio de cada función. mcount es generalmente proporcionado por herramientas de perfilado como gprof, pero también puede implementarlo usted mismo. No obstante, usted debe asegurarse de que

  • mcount tiene vinculación C (y no es C++ - estilo de nombre-mutilado), es decir, mediante la aplicación como una función C y compilar con un compilador de C puro como gcc.
  • la unidad de compilación que contiene mcount no se compila con -pg.
Cuestiones relacionadas