C++ Class Design Advice

I have a Node class template, which takes a Data type as a template parameter:

template <class T_Data>
class Node
{
};

The Node class is able to notify the user/listener on some events. This functionality is implemented using libsigc++ signals, but before the signal is emitted, the Node notifies a handler object which does some processing and decided whether to emit the signal or not. This handler object exists because in some cases I want node objects to handle their oen events, blocking signals.

The common solution is to give Node virtual methods which anyone can override in a derived class, but since Node uses references to itself and creates objects of its own type, it's easier to have a HandlerBase class and let people derive the handler.

Everything went great until I write a handler class and I wanted my nodes to use it. But in order to enable the new handler, I need to call a static Node method, Node::set_event_handler(). It means I have to remember to call it somewhere. If anyone wants to use my handler, they have to remember to set the handler in main() or in a ctor of some main class, maybe their Window class in a GUI app.

template <class T_Data>
class Node
{
public:
     static void set_event_handler (std::unique_ptr <HandlerBase> new_handler);
private:
     static std::unique_ptr <HandlerBase> event_handler;
};

So I came up with two possible solutions:

  1. Put the call to set_handler() in some main class I have
  2. Add a T_Handler template parameter to Node class

Currently, the static handler field is set to a new HanderBase, which ignores all signals. If I use the template parameter, it will be possible to have the same Data type with different handlers, and the static field will be set in the initialization, so no extra work will be needed.

The question is, whether the T_Handler not just adds "clutter" to Node, making it less "clean" in the sense of adding a template parameter just for the handler type, which many Node users don't even need.

Actually, I could also give T_Handler a default value, so users can forget about it of they don't need it, but I'm still curious which design is potentially better.

Upvotes: 1

Views: 334

Answers (1)

Richard Walters
Richard Walters

Reputation: 1474

Of course it adds clutter and makes it less clean. However, is it really a big concern? It depends on your perspective, I suppose.

If you look at many of the templates in the standard library, you'll see template parameters that most users don't need. Default values as well as typedef are used to hide this clutter. For example, see std::basic_string, where:

  • Most users don't care about the traits or Alloc, so there are default values for these parameters
  • A popular value for charT is simply char, so the std::string type is defined as shorthand.

Note that this clutter is only hidden. It will come out to bite you if you ever need to debug your code and you are looking at the types of your variables in the debugger. ;)

Upvotes: 1

Related Questions