Skip to content

C++ Runtime Types: Find All Classes Derived From a Base Class (1)

I’m working on a program in C++, recently converted from C.  I’m redesigning the error logging subsystem to have type-safety, log-to-database, and also to make it possible to generate a list of all the errors in the system.  So what I’ve decided to do is have a base class CError, and require that all the errors derive from it:

class CError
{
public:
  typedef const char * format_type;
  typedef std::string message_type;

  virtual format_type Format() const = 0;
  virtual format_type Message() const { return Format(); }

  virtual ~CError() {}

private: // disable copying
  CError( const CError& );
  CError& operator=( const CError& );
};

And an actual error message might look like this:


class CUnableToOpenFile : public CError
{
public:
  CUnableToOpenFile( const wchar_t * psPath, DWORD dwError = GetLastError() )
  { Init( psPath, dwError ); }

  format_type Format() const { return "Unable to open file {0}: {1}"; }
};

Init is a function that converts the error code to a string and uses fastformat to format the string.  (I’m omitting some of the mechanism here, because I want to talk about the runtime type discovery issue.)

OK, so now what?  I have a bunch of types that derive from CError, and no way to enumerate them at runtime.

Well maybe I could do what ruby does, enumerate all the classes in the type system and see if they can be cast down to CError.  I could do that if I had a list of all the classes in the system, which Ruby does have; the  C++ runtime has it too (to implement type_info and dynamic_cast), but it can’t give it to me.  I still need to separately maintain some a list of (at least) the types I’m interested in.