【问题标题】:C++ inheritance: string construction in constructorC++ 继承:构造函数中的字符串构造
【发布时间】:2020-04-22 05:12:38
【问题描述】:

我目前正在学习 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() 应该返回 Nums_expection 位于 0x777fff:“Q”不在以 16 为底的字母表中

我还尝试了一个编译器宏...但是无论我尝试什么 - 将其编写为普通代码都可以正常工作。但是当我想将字符串传递给nums_exception 构造函数时,它总是会得到一个空字符串。

【问题讨论】:

  • 这种方法应该有效。请出示minimal reproducible example
  • 现在应该可以了。对于复制,可以实现class Nums public: Nums(); uint getBase() { return 2; } };
  • 我不得不做几个修复才能让它编译。请在发布之前检查您的minimal reproducible example,这样我们就不必为您做这项工作了。
  • 你是对的@lightness-races-by-sa-3-0。抱歉,这是我在这里的第一个问题。以后我会努力做得更好!

标签: c++ string stdstring


【解决方案1】:

这里有几个问题。

  1. std::to_string does not take a char.

    该参数可能会被提升为int,其值为输入的 ASCII 代码(或您使用的任何内容)。所以'x' becomes "120"。不是你想要的。

    您应该改用std::string(1, digit)

    阅读您使用的函数的文档!至少,单独测试程序的单元。

     

  2. what() 返回一个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)

【讨论】:

  • 非常感谢!我对悬空指针的错...而且我以前不知道std::string(1, x)...本来会使用if isalpha(x)左右。哈哈
猜你喜欢
  • 2017-08-09
  • 2019-01-21
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
  • 2023-04-03
相关资源
最近更新 更多