Re: GTK--: (offtopic) How to keep the templates' definiton outside the headers ?



Hi,

Searching better the WWW, I was able to find the original article. It's
from 
the C User's Journal http://www.cuj.com , November 1997. The solution
was to put the following in the bufferedDrawingArea.cc file:

template BufferedDrawingArea<float>;

No more need for dummy() or dummyFloat !

Ionutz

Ionut Borcoman wrote:
> 
> Hi,
> 
> Please excuse me for this 50% offtopic question ;-).
> 
> I have made a template class for ploting my data. It is based on
> Gtk_DrawingArea. It can plot any type of dat: int, float, etc. The
> header is bellow:
> 
> ///////////////////////////////////////////////////
> // bufferedDrawingArea.hh
> 
> #ifndef __bufferedDrawingArea_hh__
> #define __bufferedDrawingArea_hh__
> 
> #include <gtk--/pixmap.h>
> #include <gtk--/drawingarea.h>
> 
> // MULTIPLE PLOTS:
> // to be able to plot more drawings on the same BufferedDrawingArea
> // we must freez and unhold it before the first draw.
> // after the first draw, we must hold it.
> // before the last one we must unfreez the area.
> // in the end it is better to unhold it also.
> 
> // CAUTION: unless the x and y axes are set, errors can appear
> // as the code cannot handle rescaling of graphics relative one to other
> !
> 
> template <class T>
> class BufferedDrawingArea: public Gtk_DrawingArea
> {
> public:
>   bool hold;
>   bool freez;
> 
>   BufferedDrawingArea(const char *aName = NULL);
>   ~BufferedDrawingArea();
> 
>   void set_name(const char *aName);
>   void set_xaxes( T min, T max);
>   void set_yaxes( T min, T max);
>   void draw_line( T *ydata, int N);
>   void draw_line( T *xdata, T *ydata, int N);
> 
> private:
>   char name[32];
> 
>   T xmin;
>   T xmax;
>   T ymin;
>   T ymax;
> 
>   bool xauto;
>   bool yauto;
>   int h;
>   int w;
> 
>   GdkPixmap *pixmap;
>   GdkWindow *buff_window;
>   GtkStyle *buff_style;
> 
>   int handle_configure_event (GdkEventConfigure *event);
>   int handle_expose_event (GdkEventExpose *event);
> 
>   void show_event();
> 
> };
> 
> #endif
> 
> Some time ago I read an article about how to separate the implementation
> of the template and its declaration. (Unfortunately, I do not remember
> where I've found that article to read it again.)
> 
> The ideea is to convince the compiler to generate all the necessary
> definitions in the object file. Therefore I have this
> bufferedDrawingArea.cc file:
> 
> ///////////////////////////////////////////////////
> // bufferedDrawingArea.cc
> 
> #include "bufferedDrawingArea.hh"
> 
> // this dummy function is just to force the compiler to generate
> // the draw_line functions
> dummy(){
>   BufferedDrawingArea<float> dummyFloat;
>   dummyFloat.draw_line(NULL,0);
>   dummyFloat.draw_line(NULL,NULL,0);
> }
> 
> template <class T> long int Max( T * data, long int length)
> {
> ...
> };
> 
> // Get the index of the minimum element of a "length" vector
> template <class T> long int Min( T * data, long int length)
> {
> ...
> };
> 
> template <class T>
> BufferedDrawingArea<T>::BufferedDrawingArea(const char *aName = NULL)
>: pixmap (0)
> {
> ...
> };
> 
> template <class T>
> BufferedDrawingArea<T>::~BufferedDrawingArea()
> {
> ...
> }
> 
> // Create a new backing pixmap of the appropriate size
> template <class T>
> int BufferedDrawingArea<T>::handle_configure_event (GdkEventConfigure
> *event)
> {
> ...
> }
> 
> // Redraw the screen from the backing pixmap
> template <class T>
> int BufferedDrawingArea<T>::handle_expose_event (GdkEventExpose *event)
> {
> ...
> }
> 
> template <class T>
> void BufferedDrawingArea<T>::set_name(const char *aName){
> ...
> }
> 
> template <class T>
> void BufferedDrawingArea<T>::set_xaxes( T min, T max)
> {
> ...
> }
> 
> template <class T>
> void BufferedDrawingArea<T>::set_yaxes( T min, T max)
> {
> ...
> }
> 
> template <class T>
> void BufferedDrawingArea<T>::draw_line( T *ydata, int N)
> {
> ...
> }
> 
> template <class T>
> void BufferedDrawingArea<T>::draw_line( T *xdata, T *ydata, int N)
> {
> ...
> }
> 
> I was able to force the compiler to generate all the declarations by
> introducing the "dummy()" function.
> 
> At the begining I wanted just to include a declaration like:
> 
>   BufferedDrawingArea<float> dummyFloat;
> 
> and remove entirely the dummy(). This didn't work as the compiler didn't
> generate the code for
> 
> void BufferedDrawingArea<float>::draw_line( float*, int)
> void BufferedDrawingArea<float>::draw_line( float*, float*, int)
> 
> I was forced to introduce the explicit call of these functions in the
> dummy function to guarantee the generation of the necessary code. Any
> ideea ?
> 
> My compiler is egcs (1.0.2-0.6) on debian 2.0.
> 
> TIA,
> 
> Ionutz



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]