<< PreviousNext >>

Wrong function called

Someone came up with the following code to make it possible to mark objects as printable by simply inheriting from the Printable interface. There was also a need to see what type certain objects had at runtime, so the StrType interface was added as well.

To easily print Printable objects, a printf-clone was implemented as myPrint. This function takes a printf format string (just % for now, no options), and a couple of objects that should inherit from the Printable interface. However, something seems to be wrong!

What is wrong, and how would you solve the problem?

main.cpp

#include <string>
#include <cstdarg>
#include <cstdio>

using namespace std;

/**
 * Interface implemented by classes to get a string
 * representation of their type.
 */
class StrType {
public:
  virtual string type() const = 0;
};


/**
 * Interface implemented by classes that enables them
 * to print themselves.
 */
class Printable {
public:
  virtual string toS() const = 0;
};


/**
 * Simple text class that can report its type, and of course
 * it is also printable!
 */
class Text : public StrType, public Printable {
public:
  Text(const string &text) : text(text) {}

  virtual string type() const {
    return "Text";
  }

  virtual string toS() const {
    return "B: " + text;
  }

private:
  string text;
};


/**
 * Our own print utility! It will print any object that is 'Printable'!
 * Replaces each % with the n'th parameter, much like printf, but without
 * additional format specifiers.
 */
void myPrint(const char *fmt, ...) {
  va_list list;
  va_start(list, fmt);

  for (const char *p = fmt; *p; p++) {
    if (*p == '%') {
      const Printable *p = va_arg(list, const Printable *);
      printf("%s", p->toS().c_str());
    } else {
      putchar(*p);
    }
  }

  va_end(list);
}

/**
 * Small test. Should print "Hello world".
 */
int main() {
  Text hello("Hello"), world("world");

  myPrint("% %\n", &hello, &world);

  return 0;
}

Download files

Answer and comments