0

An object has a string and needs to be constructed.

#include <string>

class SDLException
{
private:
    std::string what_str;
public:
    SDLException(const std::string &msg);
    ~SDLException(void);
};

The string has a hidden dependency that i need to consider (SDL_GetError()). I can construct the string in a function. But i do not know how to use a return value of that function to initialize a string member.

#include "SDLException.hpp"

#include <sstream>
#include <string>
#include <SDL.h>

static void buildSTR(const std::string &msg)
{
    std::ostringstream stream;
    stream << msg << " error: " << SDL_GetError();
    std::string str =  stream.str();
    //if i return a string here it would be out of scope when i use it
}

SDLException::SDLException(const std::string &msg)
    : what_str(/*i want to initialise this string here*/)
{}

SDLException::~SDLException(void){}

How can i initialize the member what_str with a minimum amount of overhead? The content of what_str should be equal to the content of str.

Johannes
  • 6,490
  • 10
  • 59
  • 108
  • *"if i return a string here it would be out of scope when i use it"* I don't think so. – Axalo Feb 23 '15 at 21:32
  • 1
    Have `std::string buildSTR(const std::string& msg)` return `str` (or just `stream.str()`), then use `: what_str(buildSTR(msg))` in your exception construct-initializer list. Move-semantics and RVO should do the rest for you. – WhozCraig Feb 23 '15 at 21:37

2 Answers2

5

Your buildSTR() function should return a string:

static std::string buildSTR(const std::string &msg)
{
    std::ostringstream stream;
    stream << msg << " error: " << SDL_GetError();
    return stream.str();
}

There is then no issue using it here:

SDLException::SDLException(const std::string &msg)
    : what_str(buildSTR(msg))
{ }

Alternatively, you could omit your sstream include and simply use string concatenation, because std::string has an operator overload to allow concatenation of const char*. Ex:

SDLException::SDLException(const std::string &msg)
    : what_str(msg + " error: " + SDL_GetError())
{ }
Julian
  • 1,688
  • 1
  • 12
  • 19
  • Thanks. I found some more information on that and will read it tomorrow. http://stackoverflow.com/questions/3106110/what-is-move-semantics – Johannes Feb 23 '15 at 21:48
  • 2
    Don't forget to also read up on the highly relevant RVO and NRVO, and also don't forget to compare the performance of copying the string by accident with the performance of throwing an exception (hint: on many platforms throwing will be vastly more expensive). – Puppy Feb 23 '15 at 21:55
0

You're almost there. Change BuildSTR to return a string and return your str from BuildSTR. Then call buildSTR(msg) to initialize what_str.

Wilf Rosenbaum
  • 518
  • 3
  • 10
  • 1
    There's no need for it to be a reference. Move semantics and RVO/NRVO can easily take care of any performance problem, and compared to throwing, copying a small string is nothing anyway. – Puppy Feb 23 '15 at 21:54
  • Oops - I had string in mind but wrote string&. You're right of course, thanks guys I edited my answer. – Wilf Rosenbaum Feb 23 '15 at 22:26