C++ 继承:构造函数中的字符串构造
C++ inheritance: string construction in constructor
我目前正在学习 C++ 并正在实现一个用于异常处理的示例程序。
主程序实现了一个具有任意基数的数字系统。
我用函数 virtual const char *what();
做了一个 class nums_exception : public std::exception
#include <stdexcept>
#include <sstream>
class Nums
{
public:
Nums() {}
unsigned int getBase() { return 2; }
};
class nums_exception: public std::exception
{
public:
nums_exception(Nums* obj, std::string errortext);
virtual ~nums_exception();
virtual const char *what() const noexcept;
const Nums *failObj();
private:
std::string errortext;
Nums *obj;
};
nums_exception::nums_exception(Nums *obj, std::string errortext)
: errortext(errortext)
, obj(obj)
{
}
nums_exception::~nums_exception() = default;
const char *nums_exception::what() const noexcept
{
if (this->errortext.size() == 0)
{
return "Nums exception!";
}
else
{
std::stringstream ret;
ret << "Nums exception at "
<< obj
<< " :"
<< this->errortext;
return ret.str().c_str();
}
}
// Now i derived nums_bad_digit, which should look like this:
class nums_bad_digit: public nums_exception
{
public:
nums_bad_digit(Nums* obj, uint base, char digit);
virtual ~nums_bad_digit() override;
static std::string ERRORTEXT(Nums *obj, char digit);
private:
std::string errortext;
const uint base;
Nums *obj;
};
inline std::string nums_bad_digit::ERRORTEXT(Nums *obj, char digit)
{
return std::string(std::to_string(digit) + " not in alphabet for base " +
std::to_string(obj->getBase()) + '.');
}
nums_bad_digit::nums_bad_digit(Nums *obj, uint base, char digit)
: nums_exception(obj, ERRORTEXT(obj, digit))
, base(base)
{
}
nums_bad_digit::~nums_bad_digit() = default;
int main()
{
Nums n;
throw nums_bad_digit(&n, 42, 'x');
}
这里我尝试使用静态方法达到我的目标。
我想构建一个现成的错误消息,说明我抛出此异常的确切原因,然后将其传递给 nums_exception
构造函数。例如,nums_bad_digit::what() 应该 return
Nums_expection 位于 0x777fff:'Q' 不在以 16 为基数的字母表中。
我还尝试了一个编译器宏...但无论我尝试什么 - 将其编写为正常代码都可以正常工作。但是当我想将字符串传递给 nums_exception
构造函数时,它总是会得到一个空字符串。
这里有几个问题。
std::to_string
does not take a char
.
参数可能会提升为 int
,其值是输入的 ASCII 码(或您使用的任何内容)。所以'x'
becomes "120"
。不是你想要的。
您应该改用 std::string(1, digit)
。
阅读您使用的函数的文档!至少,单独测试程序的单元。
what()
returns一个const char*
,但是它指向的数据已经死了
字符串流是本地的,字符串是临时的,所以这个指针立即悬空。相反,我会在构造函数中生成完整的字符串,并将其存储为成员,以便它在异常对象存在时一直存在。
所以,这个:
nums_exception::nums_exception(Nums *obj, std::string errortext)
: obj(obj)
{
if (errortext.size() == 0)
{
this->errortext = "Nums exception!";
}
else
{
std::stringstream ret;
ret << "Nums exception at "
<< obj
<< " :"
<< errortext;
this->errortext = ret.str();
}
}
还有这个:
const char *nums_exception::what() const noexcept
{
return errortext.c_str();
}
还有这个:
inline std::string nums_bad_digit::ERRORTEXT(Nums *obj, char digit)
{
return std::string(1, digit) + " not in alphabet for base " +
std::to_string(obj->getBase()) + '.';
}
(live demo)
我目前正在学习 C++ 并正在实现一个用于异常处理的示例程序。
主程序实现了一个具有任意基数的数字系统。
我用函数 virtual const char *what();
nums_exception : public std::exception
#include <stdexcept>
#include <sstream>
class Nums
{
public:
Nums() {}
unsigned int getBase() { return 2; }
};
class nums_exception: public std::exception
{
public:
nums_exception(Nums* obj, std::string errortext);
virtual ~nums_exception();
virtual const char *what() const noexcept;
const Nums *failObj();
private:
std::string errortext;
Nums *obj;
};
nums_exception::nums_exception(Nums *obj, std::string errortext)
: errortext(errortext)
, obj(obj)
{
}
nums_exception::~nums_exception() = default;
const char *nums_exception::what() const noexcept
{
if (this->errortext.size() == 0)
{
return "Nums exception!";
}
else
{
std::stringstream ret;
ret << "Nums exception at "
<< obj
<< " :"
<< this->errortext;
return ret.str().c_str();
}
}
// Now i derived nums_bad_digit, which should look like this:
class nums_bad_digit: public nums_exception
{
public:
nums_bad_digit(Nums* obj, uint base, char digit);
virtual ~nums_bad_digit() override;
static std::string ERRORTEXT(Nums *obj, char digit);
private:
std::string errortext;
const uint base;
Nums *obj;
};
inline std::string nums_bad_digit::ERRORTEXT(Nums *obj, char digit)
{
return std::string(std::to_string(digit) + " not in alphabet for base " +
std::to_string(obj->getBase()) + '.');
}
nums_bad_digit::nums_bad_digit(Nums *obj, uint base, char digit)
: nums_exception(obj, ERRORTEXT(obj, digit))
, base(base)
{
}
nums_bad_digit::~nums_bad_digit() = default;
int main()
{
Nums n;
throw nums_bad_digit(&n, 42, 'x');
}
这里我尝试使用静态方法达到我的目标。
我想构建一个现成的错误消息,说明我抛出此异常的确切原因,然后将其传递给 nums_exception
构造函数。例如,nums_bad_digit::what() 应该 return
Nums_expection 位于 0x777fff:'Q' 不在以 16 为基数的字母表中。
我还尝试了一个编译器宏...但无论我尝试什么 - 将其编写为正常代码都可以正常工作。但是当我想将字符串传递给 nums_exception
构造函数时,它总是会得到一个空字符串。
这里有几个问题。
std::to_string
does not take achar
.参数可能会提升为
int
,其值是输入的 ASCII 码(或您使用的任何内容)。所以'x'
becomes"120"
。不是你想要的。您应该改用
std::string(1, digit)
。阅读您使用的函数的文档!至少,单独测试程序的单元。
what()
returns一个const char*
,但是它指向的数据已经死了字符串流是本地的,字符串是临时的,所以这个指针立即悬空。相反,我会在构造函数中生成完整的字符串,并将其存储为成员,以便它在异常对象存在时一直存在。
所以,这个:
nums_exception::nums_exception(Nums *obj, std::string errortext)
: obj(obj)
{
if (errortext.size() == 0)
{
this->errortext = "Nums exception!";
}
else
{
std::stringstream ret;
ret << "Nums exception at "
<< obj
<< " :"
<< errortext;
this->errortext = ret.str();
}
}
还有这个:
const char *nums_exception::what() const noexcept
{
return errortext.c_str();
}
还有这个:
inline std::string nums_bad_digit::ERRORTEXT(Nums *obj, char digit)
{
return std::string(1, digit) + " not in alphabet for base " +
std::to_string(obj->getBase()) + '.';
}