Q. Can a Good Parasite Class Declare Additional Member Functions?
A. Yes, it can. You may add more member functions to the good parasite as long as those members aren't virtual. Of course, you cannot add any of the member functions and operators that are declared =delete.
As examples, you might add a member function called write_header() to the Zeroer class, which writes a header to the cleared buffer, or you might declare a member function that transforms the buffer to uppercase letters. Notice, however, that you cannot declare any data members in a good parasite class. In addition, such a class can have only non-virtual base classes that qualify for the empty base optimization.
Q. What's the Good Parasite Good For in the Big Picture?
A. The good parasite class is an attempt to introduce a new type of function object to C++. Unlike traditional function objects, which have non-trivial initialization and destruction overhead and include data members in many cases, the good parasite is a pure function object: The very instantiation of such an object invokes the operation that the object represents. Thus, constructing a Zeroer object essentially clears the buffer. You achieve this by using the following design guidelines:
- Tuck the operation into the constructor of the good parasite.
- Avoid any data members.
- Eliminate the destructor.
This leads to an optimal design whereby:
1 object invocation(instantiation) == 1 function call
By contrast, when you're using a traditional function object the ratio is:
1 function object invocation == 3 function calls
Where the three function calls consist of a constructor, operator(), and a destructor.
Q. If the Whole Purpose Is to Squeeze an Operation into a Constructor Call, Why Not Use a Simple Function?
A.I have no argument here. Calling a constructor amounts to calling a function, so there's no significant difference (performance-wise) between a function and a good parasite class. Hence, theoretically, you can choose a simpler design that uses a plain old function instead.
However, notice that a traditional function would require additional arguments that indicate the buffer's size and address. Forcing the programmer to pass these arguments explicitly in every function call is a security hazard. These arguments are eliminated when you use Zeroer<161>, because the size of the buffer is implicitly stored in the type of the Zeroer specialization, and the address of the buffer is cached in the thispointer.
Remember also that you can add more member functions to the good parasite, which makes this design more appealing and convenient than defining a procedural programming style list of unrelated functions.
Hopefully, this article has cleared up some of the confusion and controversy about the good parasite class and helped expand your C++ toolbox.