I'm trying to work through ways to create a class with a std::string argument, but which also handles NULL without throwing an exception. Here's an example of the code:
class myString {
public:
myString(const std::string& str) : _str(str) {}
std::string _str;
};
int main() {
myString mystr(NULL);
printf("mystr = <%s>\n", mystr._str.c_str());
return 0;
}
Intuitively, you'd think that this program should print "mystr = <>" and exit successfully, but instead with g++ it gives this error:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct NULL not valid
How can I change this class so that it translates NULL into "" instead of throwing a logic_error exception?
(Postscript: As you'd suspect, the "real" implementation is a bit more complicated than this example, having several arguments in the constructor and doing more interesting things with _str -- and properly keeping it private. The motivation behind this example is that programmers in our team will tend to use NULL in this context for historical purposes, and the compiler won't catch this. Retraining everyone to always use "" is relatively hard. Alternatively, a clever solution would be easy)
What actually happens here is that NULL
is interpreted as char const*
and is being tried to be converted to std::string
(you can convert C-strings of type char*
into STL strings, right?).
To handle it, you may add another constructor
class myString {
public:
myString(const std::string& str) : _str(str) {}
myString(const char* str) : _str(str==NULL?"":std::string(str))
{ /* and do something special in the body */ }
std::string _str;
};
But if you need nothing special there, the better way would be
class myString {
public:
myString(const std::string& str = "") : _str(str) {}
std::string _str;
};
int main() {
myString mystr; //no () here!
printf("mystr = <%s>\n", mystr._str.c_str());
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With