Do it this way? Or that way? What’s best?

Long, heated debates, and long, painful agonizing over the choice, often result from “this, or that?”. E.g., return by value or take an in/out argument? The practical answer is often just “yes, both, thank you”, like Winnie the Pooh, and in some cases the practical answer is “a different way”, but for some mysterious reason the practical answer can be very hard to see.

– Would you like condensed milk, Rabbit, nodding head
or honey on your bread? Rabbit, shaking head
– Both. But never mind the bread, please. Just a small helping, if you please. Winnie the Pooh
– Huh, there you are. Rabbit gives Pooh a single drop of honey
– … Is, uh, something wrong? Rabbit (Pooh looks at him disappointedly)
– Well, I did mean a little larger “small helping”. Winnie the Pooh

In my last posting (and the one before that) I mentioned my vacillation and agonizing over whether ConstructorArgForwarder should have a virtual destructor, or not. Of course, with 20-20 hindsight the practical answer was just “yes”. Just let the client code decide:

In file [progrock/cppx/generic/DestructorKind.h]:

namespace progrock { namespace cppx {

    enum DestructorKind { destructorLikeBaseClass, virtualDestructor };
    template< DestructorKind > struct DestructorImpl;

    struct DestructorImpl< destructorLikeBaseClass >

    struct DestructorImpl< virtualDestructor >
    { virtual ~DestructorImpl() {} };

} }  // namespace progrock::cppx

In file [progrock/cppx/arguments/ConstructorArgForwarder.h]:

namespace progrock { namespace cppx {

        typename Type,
        DestructorKind destructorKind = destructorLikeBaseClass
    class ConstructorArgForwarder
        : public Type
        , private DestructorImpl< destructorKind >
        typedef Type        Base;

        // As before.

} }  // namespace progrock::cppx

I guess that this concept of offering a late choice of virtual destructor or not, was just too novel or alien or newfangled (whatever) to be popped up by my alternatives generator. It seemed to me that it had to be either/or: either you have a virtual destructor, or not, and you must choose. But often the apparent need for an early, final choice is just because one becomes trapped in Bad™ either/or thinking.

By the way, concerning refactoring in general: if you’ve followed my postings here closely (yeah, fat chance, but I guess perhaps someone does :-)) you’ll note that I’ve changed the physical packaging of files, introducing some new subdirectories like [generic] and [arguments]. That’s a kind of refactoring that as far as I know is seldom discussed, perhaps because it generally can be so extremely costly to do: #includes may have to be fixed up everywhere, people have to be re-familiarized with the new structure. But happily in my case, working alone on a small library, the change was essentially cost-free. I’ve long since put aside the application code and other library code that uses this library, and will only revisit that when I get the cppx library up in shape as I want it. I wonder whether there are free refactoring tools that can do this kind of physical packaging refactoring?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s