Ich verwende in einem aktuellen C++ Projekt die C Funktion scandir(). Diese erlaubt die Adresse einer Filterfunktion zum filtern der Dateinamen zu übergeben. Wenn ich das jetzt in eine C++ Klasse einbaue, geht das nur, wenn die Filterfunktion statisch ist.
Der Anwender soll aber auch die Möglichkeit haben, einen Filterstring zu übergeben. Also muss die Filterfunktion Zugriff auf den Filter-Puffer haben. Aber genau das geht von statische Funktionen nur, wenn man zusätzlich einen Zeiger auf die aktuelle Instanz übergibt, was hier nicht mit dem Prototyp von scandir() zusammenpasst.
Ich habe das Problem erstmal dadurch gelöst, das ich den Puffer für den Filterstring auch statisch gemacht habe. Aber das erscheint mir irgendwie unsauber, da das bedeutet dass alle Instanzen meiner Klasse den selben Filterstring benutzen müssen. Andererseits ist es unwahrscheinlich, dass eine Klasse zum Anzeigen eines Verzeichnisbaums mehrfach in einer Anwendung vorkommt.
Um das zu verdeutlichen, hier mal ein Auszug aus dem aktuellen Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | // static char*pattern_buf; char * DirTree::pattern_buf = NULL; ... int DirTree::get_files( char *** lst ) { ... char * path = new char[1024]; int num_entries, i; struct dirent** namelist, **list; char ** filelist = NULL; char ** p; int l; ... if((num_entries=scandir( path, &namelist, &file_sel, alphasort )) > 0 ) { filelist = new char * [num_entries]; p = filelist; for( i = 0, list = namelist; i < num_entries; i++, list++ ) { //return fl_filename_match( (*list)->d_name, pattern_buf ); l = strlen( (*list)->d_name ) + 1; *p = new char [l]; strcpy( *p, (*list)->d_name ); p++; free( *list ); } free( namelist ); } *lst = filelist; return num_entries; } // static int file_sel( const struct dirent * dp ); int DirTree::file_sel( const struct dirent * dp ) { if( dp->d_type == 8 ) { // DT_REG if( dp->d_name[0] != '.' ) { return fl_filename_match( dp->d_name, pattern_buf ); // FLTK Funktion } } return 0; } |
Wie man hier sieht, wird das Ergebnis noch einmal umkopiert. Daraus ergäbe sich auch die Möglichkeit, erstmal nur nach d_type == Datei zu filtern und dann in der Funktion get_files() noch einmal zu filtern, wodurch aber vorübergehend deutlich mehr Speicherplatz erforderlich währe (je nach Filterstring)
Meine Frage ist jetzt, welche Vorgehensweise sollte ich wählen?