I would do something like this:
class ScoreText {public: ScoreText(int x, int y, TTF_Font * font, SDL_Color color) : current_score(0) , font(font) , cache(NULL) , color(color) { dst.x = x; dst.y = y; } ~ScoreText() { clear_cache(); } void update(int new_score) { if (current_score == new_score) return; current_score = new_score; clear_cache(); } void set_position(int x, int y) { dst.x = x; dst.y = y; } bool render(SDL_Surface * s) { SDL_Surface * text = get_cached(); if (text != NULL) { int result = SDL_BlitSurface(text, NULL, s, &dest); if (result == -2) clear_cache(); } return result == 0; }private: void clear_cache() { if (cache != NULL) SDL_FreeSurface(cache); cache = NULL; } SDL_Surface * get_cached() { if (cache == NULL) { char buf[40]; sprintf(buf, "%d", current_score); cache = TTF_RenderText_Solid(font, buf, color); } return cache; } int current_score; SDL_Rect dest; SDL_Surface * cache; SDL_Color color;};
sprintf is ideal choice. We have a well known range, it avoids potential heap allocations, and doesn't require third-party libraries and SDL is a C library, so some 'print_score()' function could be provided as straight C function. In addition, it works on C strings, same as SDL, so there is no need to bring in std::string.
For more generic printing, the alternatives were listed above. Stringstream is a must when several things need to be printed, lexical_cast can be used to work with std::string. printf in general is very clumsy when dealing with straight user input simply due to manual memory management - but this is not the case here.
Good code is primarily about choosing proper compromises. Unless any other constraints are given, stringstream would be generic choice. But this is a common problem today - massive over-engineering without any critical thinking about the actual problem to be solved.
The task here is to
Print Score In Pong Game. Score will not be represented with 272 bits. It will probably be 0 to 10.
Instead, rather than writing 500 lines of code to
Print a freeking int, going through all the SDL documentation to properly handle all the return codes would be much more productive. When must a surface be freed, what happens if surface is lost (I don't handle this case thoroughly above), which encoding to use, etc... 999:1 chance says that someone will forget to call FreeSurface and leak memory long before their code breaks due to 272-bit integer stack buffer overflow.