我想通过在将字符串返回到 What() 之前连接字符串来创建自定义异常。我知道还有其他方法可以达到想要的结果,我只是想了解为什么代码会这样。代码不起作用的原因是因为 c_str() 不是深层副本吗?如果是这样,我应该避免一般使用它吗?另外为什么第二段代码的行为与第一段不同?
class InvalidFormat : public std::exception
{
private:
std::string _exceptionValue;
public:
InvalidFormat(std::string str);
const char *what() const throw();
};
InvalidFormat::InvalidFormat(std::string str) : _exceptionValue(str) {}
const char *InvalidFormat::what() const throw() {
return ("Format is invalid => " + _exceptionValue).c_str();}
//doesn't output anything
const char *InvalidFormat::what() const throw() {
return std::string("Format is invalid => ").assign_exceptionValue).c_str();}
//outputs random data
以下代码对临时
c_str()
调用 std::string
,其生命在完整表达后结束(在 ;
):
return ("Format is invalid => " + _exceptionValue).c_str(); // UB-prone
当
InvalidFormat::what()
返回时,返回的指针指向已释放并消失的内存,这是未定义的行为。这再好不过了:
return std::string("Format is invalid => ").assign_exceptionValue).c_str(); // UB-prone
如果要返回指向它的非拥有指针,则必须存储连接结果:
InvalidFormat::InvalidFormat(std::string str)
: _exceptionValue("Format is invalid => " + str)
{}
const char *InvalidFormat::what() const throw()
{
return _exceptionValue.c_str(); // OK
}