[ Pobierz całość w formacie PDF ]
.The catch is that all methods of an abstract base class must be implementedfor the client because they will be called.For a device driver this is perhaps obvi-ous, but a device driver is not exactly a representative scenario for callback func-tions.A window is much more typical: some clients have to worry about expo-sures and others could not care less  why should they all have to implement allmethods?An abstract base class restricts the architecture of a class hierarchy.Withoutmultiple inheritance a client must belong to a particular part of the class tree headedby the abstract base class, regardless of its actual role within an application.As anexample, consider a client of a window managing a list of graphical objects.Theelegant solution is to let the client belong to a subclass of List but the implementa-tion of a window forces the client to be something like a WindowHandler.As wediscussed in section 4.9 we can make an aggregate and let the client contain a Listobject, but then our class hierarchy evolves according to the dictate of the systemrather than according to the needs of our application problems.Finally, an abstract base class defining callback functions tends to define noprivate data components for its objects, i.e., the class declares but does not definemethods and the objects have no private state.While this is not ruled out by theconcept of a class it is certainly not typical and it does suggest that the abstractbase class is really just a collection of functions rather than of objects and methods. 10.3 Delegates 113___________________________________________________________________________10.3 DelegatesHaving made a case against abstract base classes we need to look for a better idea.It takes two to callback: the client object wants to be called and the host does thecalling.Clearly, the client object must identify itself to the host, if it wants the hostto send it a message, but this is all that is required if the host can ask the clientwhat callbacks it is willing to accept, i.e., what methods it can respond to.It is significant that our viewpoint has shifted: an object is now part of the call-back scenario.We call such an object a delegate.As soon as a delegate announcesitself to the host, the host checks what callbacks the delegate can handle and laterthe host makes precisely those calls which the delegate expects.As an example we implement a simple framework for a text filter, i.e., a pro-gram which reads lines from standard input or from files specified as arguments,manipulates them, and writes the results to standard output.As one application welook at a program to count lines and characters in a text file.Here is the main pro-gram which can be specified as part of the implementation file Wc.dc:int main (int argc, char * argv []){ void * filter = new(Filter(), new(Wc()));return mainLoop(filter, argv);}We create a general object filter and give it as a delegate an application-specific Wcobject to count lines and characters.filter receives the arguments of our programand runs the mainLoop() with callbacks to the Wc object.% WcClass: Class Wc: Object {unsigned lines; // lines in current fileunsigned allLines; // lines in previous filesunsigned chars; // bytes in current fileunsigned allChars; // bytes in previous filesunsigned files; // files completed%int wc (_self, const Object @ filter, \const char * fnm, char * buf);int printFile (_self, const Object @ filter, \const char * fnm);int printTotal (_self, const Object @ filter);%}The methods in Wc do nothing but line and character counting and reporting theresults.wc() is called with a buffer containing one line:% Wc wc { // (self, filter, fnm, buf)%casts++ self  > lines;self  > chars += strlen(buf);return 0;}Once a single file has been processed, printFile() reports the statistics and addsthem to the running total: 114 10 Delegates  Callback Functions___________________________________________________________________________% Wc printFile { // (self, filter, fnm)%castsif (fnm && strcmp(fnm, " "))printf("%7u %7u %s\n",self  > lines, self  > chars, fnm);elseprintf("%7u %7u\n", self  > lines, self  > chars);self  > allLines += self  > lines, self  > lines = 0;self  > allChars += self  > chars, self  > chars = 0;++ self  > files;return 0;}fnm is an argument with the current filename.It can be a null pointer or a minussign; in this case we do not show a filename in the output.Finally, printTotal() reports the running total if printFile() has been called morethan once:% Wc printTotal { // (self, filter)%castsif (self  > files > 1)printf("%7u %7u in %u files\n",self  > allLines, self  > allChars, self  > files);return 0;}Wc only deals with counting.It does not worry about command line argu-ments, opening or reading files, etc.Filenames are only used to label the output,they have no further significance.10.4 An Application Framework  FilterProcessing a command line is a general problem common to all filter programs.Wehave to pick off bundled or separated flags and option values, we must recognizetwo minus signs -- as the end of the option list and a single minus sign - addition-ally as standard input, and we may need to read standard input or each file argu-ment.Every filter program contains more or less the same code for this purpose,and macros such as MAIN [Sch87, chapter 15] or functions such as getopt(3) helpto maintain standards, but why regurgitate the code in the first place?The class Filter is designed as a uniform implementation of command line pro-cessing for all filter programs.It can be called an application framework because itestablishes the ground rules and basic structure for a large family of applications.The method mainLoop() contains command line processing once and for all anduses callback functions to let a client deal with the extracted arguments:% mainLoop { // (self, argv)%castsself  > progname = * argv ++; 10.4 An Application Framework    Filter  115___________________________________________________________________________while (* argv && ** argv ==    ){ switch (* ++ * argv) {case 0: // single   * argv; //.is a filenamebreak; // [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • agnieszka90.opx.pl