Example: tourism industry

Wrapping C ++ Member Function Calls - Bjarne Stroustrup

Wrapping C++ Member Function CallsBjarne StroustrupAT&T Labs - ResearchFlorham Park, New JerseyUSAABSTRACTThis paper presents a simple, general, and efficient solution to the old problem of Wrapping Calls to an object in pairs of prefix and suffix code. The solution is alsonon-intrusive, applies to existing classes, allows the use of several prefix/suffix pairs, andcan be implemented in 15 simple lines of Standard C++. A robust version of the wrapperis also presented. The claim of efficiency is backed by paper is organized around a series of examples evolving the basic idea into a finalrobust template IntroductionOften, we want to wrap a piece of code with some prefix code and some suffix code.

- 4 - 4 Suffix Unfortunately, it was not obvious how to extend the templated P Pr re ef fi ix x approach to deal with suffixes. How-ever, it can be done.

Tags:

  Call, Members, Functions, Wrapping, Wrapping c member function calls

Information

Domain:

Source:

Link to this page:

Please notify us if you found a problem with this document:

Other abuse

Transcription of Wrapping C ++ Member Function Calls - Bjarne Stroustrup

1 Wrapping C++ Member Function CallsBjarne StroustrupAT&T Labs - ResearchFlorham Park, New JerseyUSAABSTRACTThis paper presents a simple, general, and efficient solution to the old problem of Wrapping Calls to an object in pairs of prefix and suffix code. The solution is alsonon-intrusive, applies to existing classes, allows the use of several prefix/suffix pairs, andcan be implemented in 15 simple lines of Standard C++. A robust version of the wrapperis also presented. The claim of efficiency is backed by paper is organized around a series of examples evolving the basic idea into a finalrobust template IntroductionOften, we want to wrap a piece of code with some prefix code and some suffix code.

2 For example:g gr ra ab b-l lo oc ck k d do o-s so om me et th hi in ng g r re el le ea as se e-l lo oc ck kb be eg gi in n-t tr ra an ns sa ac ct ti io on n d do o-s so om me et th hi in ng g e en nd d-t tr ra an ns sa ac ct ti io on nt tr ra ac ce e-e en nt tr ry y d do o-s so om me et th hi in ng g t tr ra ac ce e-e ex xi it tTypically, there is a prefix/suffix pair that should be applied to many different sections of code. In particu-lar, in a language with classes such as C++ the problem often becomes one of ensuring that ap pr re ef fi ix x()is called before a call of a Member Function ands su uf ff fi ix x()after the call .

3 This is easily achieved explicitlyfor a few Calls . For example:v vo oi id d f fc ct t(X X*p p){p pr re ef fi ix x() ;p p->f f() ;s su uf ff fi ix x() ;p pr re ef fi ix x()p p->g g() ;s su uf ff fi ix x() ;}However, application programmers must remember to bracket each call in its properp pr re ef fi ix x()/s su uf ff fi ix x() Calls . This is tedious and error obvious alternative is to add thep pr re ef fi ix x()/s su uf ff fi ix x() Calls to the definitions of the Member functionsthat need them. For example:c cl la as ss s X X{p pu ub bl li ic c:v vo oi id d f f() {p pr re ef fi ix x() ; / *f f s s o ow wn n s st tu uf ff f*/s su uf ff fi ix x() ; }v vo oi id d g g() {p pr re ef fi ix x() ; / *g g s s o ow wn n s st tu uf ff f*/s su uf ff fi ix x() ; }/ /.}

4 };Published in the June 2000 issue of "The C++ Report". All rights reserved- 2 -v vo oi id d f fc ct t(X X*p p){p p->f f() ;p p->g g() ;}This solves the problem for the class user, but is still tedious for the class implementer. Worst of all, thissolution requires foresight by the class implementer. Because the solution is intrusive the class memberfunction code must be modified to add, remove, or change a suffix Wrapping can only be done by some-one able and willing to modify the source advantage of this approach is that it allows some, but not all functions to be wrapped. This cansometimes be a significant advantage.

5 Consider the case where the prefix/suffix provides locking. That is,the class is a form of monitor [Hoare,1974]. In that case, it is not uncommon that a few functions can beperformed without locking because they don t modify shared data or access only data that is accessed andmodified atomically [Mitchell,1979].This paper will concentrate on the case where every operation on a class needs to be History Wrapping is an old problem that has been solved many times in various languages and contexts. Moni-tors provide a solution to the problem of controlling access to a resource in a concurrent system by wrap-ping Calls in a acquire-lock-or-wait and release-lock pair.

6 Many languages provide primitives for wrappingcode in acquire/release lock pairs (for example, Mesa sM MO ON NI IT TO OR R[Mitchell,1979], Java ss sy yn nc ch hr ro on ni iz ze ed d[Lea,1997], and Modula-3 sL LO OC CK K[Nelson,1991]).More general solutions are provided by CLOS where a pair of:b be ef fo or re eand:a af ft te er rmethods can wrapcalls to objects of classes derived from the one providing the:b be ef fo or re eand:a af ft te er rmethods [Keene,1989]. Ibriefly adopted a variant of that idea for C++ s direct ancestor C with Classes [ Stroustrup ,1994]. There, onecould define a Function that would implicitly be called before every call of every Member Function (exceptthe constructor) and another that would be implicitly called before every return from every Member func-tion (except the destructor).

7 The functions providing this prefix/suffix semantics were calledc ca al ll l()andr re et tu ur rn n(). They were used to provide synchronization for the monitor class in the original task library[ Stroustrup ,1980]:c cl la as ss s m mo on ni it to or r{/ /..c ca al ll l() { /*grab lock*/ }r re et tu ur rn n() { /*release lock*/ }/ /..};c cl la as ss s X X:p pu ub bl li ic c m mo on ni it to or r{p pu ub bl li ic c:v vo oi id d f f() ;v vo oi id d g g() ;/ /..};v vo oi id d f fc ct t(X X*p p){p p->f f() ; / /monitor:: call (); f() s own stuff; monitor::return()p p->g g() ; / /monitor:: call (); g() s own stuff; monitor::return()} call and return functions were removed from the language because nobody (but me) used them and becauseI completely failed to convince people thatc ca al ll l()andr re et tu ur rn n()had important 1988, Mike Tiemann suggested an alternative solution called wrappers [Tiemann,1988]:s st tr ru uc ct t f fo oo o{f fo oo o() ; f fo oo o() ;Published in the June 2000 issue of "The C++ Report".}

8 All rights reserved- 3 -v vi ir rt tu ua al l i in nt t()f fo oo o(i in nt t(f fo oo o: :*p pm mf f)(i in nt t) ,i in nt t i i) / /virtual wrapper{p pr re ef fi ix x() ;i in nt t r r= (t th hi is s->*p pm mf f)(i i) ; / /invoke a functions su uf ff fi ix x() ;r re et tu ur rn n r r;}i in nt t g g(i in nt t) ;v vi ir rt tu ua al l i in nt t h h(i in nt t) ;};Such a wrapper Function was syntactically identified by a pair of parentheses in front of the class name andwould wrap Calls to functions of its class. The first argument of a wrapper was the Member Function toinvoke, the second and subsequent arguments were the arguments to that Function .

9 The basic idea was thata Member Function called by a user was transformed a call of the wrapper with the arguments needed for thewrapper to do the actual call . For example:v vo oi id d f fc ct t(f fo oo o*p p){i in nt t i i=p p->g g(1 1) ; / /p->()foo(&foo::f,1)i in nt t j j=p p->h h(2 2) ; / /p->()foo(&foo::g,2)/ /..}This proposal died after some experimental use because of complexities of handling argument andreturn types, and because it was intrusive. That is, you wrapped a class by deriving it from a wrapper baseclass and that base class had to be written to deal with all combinations of argument and return typesneeded by the derived classes.

10 This required too much proposal had the interesting property that the wrapper had access to the arguments and the returnvalue of a call . Also, different wrapper functions could be provided for functions with different PrefixIn the following sections, a solution to the Wrapping problem is introduced in stages. The solution does notrequire language changes; it consists of two simple template the->has long been a popular way of specifying a prefix. For example:t te em mp pl la at te e<c cl la as ss s T T>c cl la as ss s P Pr re ef fi ix x{T T*p p;p pu ub bl li ic c:P Pr re ef fi ix x(T T*p pp p) :p p(p pp p) { }T T*o op pe er ra at to or r->() { /*prefix code*/r re et tu ur rn n p p; }};X X m my y_ _o ob bj je ec ct t;P Pr re ef fi ix x<X X>p pr re ef f_ _o ob bj j(&m my y_ _o ob bj je ec ct t) ; / /available for prefixed usev vo oi id d f fc ct t(P Pr re ef fi ix x<X X>p p){p p->f f() ; / /prefix code; f()p p->g g() ; / /prefix code; g()}Note how the prefix is attached to the object (and its functions ) non-intrusively.


Related search queries