【问题标题】:Accessing string class with operator []使用运算符 [] 访问字符串类
【发布时间】:2012-03-09 08:35:39
【问题描述】:

对于培训,我正在尝试编写一个类似 std::string 的类。 我已经读过 at(int) 方法返回对字符的引用,并在索引错误(太长或负数)的情况下引发异常。 operator[] 相反不会抛出任何异常。 但是既然它返回一个引用,那么如果索引太长,它返回什么? 这是我的课程:

class string
{
    public:
    static const unsigned int length_max=100;
    string(const char* field=NULL)
    {
        if(field!=NULL)
        {
            const unsigned int length=strlen(field);
            this->field=new char[length+1];
            this->length=length;
            for(unsigned int i=0;i<=length;i++)
                this->field[i]=field[i];
        }
        else
        {
            this->field=NULL;
            length=0;
        }
    }
    string& operator=(const char* field)
    {
        const unsigned int length=strlen(field);
        if(this->field!=NULL)
            delete this->field;
        this->field=new char[length];
        this->length=length;
        for(unsigned int i=0;i<length;i++)
            this->field[i]=field[i];
        return *this;
    }
    string& operator= (const string& str)
    {
        *this=str.field;
        return *this;
    }
    operator char* ()
    {
        return field;
    }
    friend std::ostream& operator<< (std::ostream& out, string& str);
    friend std::istream& operator>> (std::istream& in, string& str);
    private:
    char* field;
    unsigned int length;
};

std::ostream& operator<<(std::ostream& out, string& str)
{
    out << str.field;
    return out;
}

std::istream& operator>> (std::istream& in, string& str)
{
    char temp[string::length_max];
    in >> temp;
    str=temp;
    return in;
}

我想让operator[],我也可以让它抛出异常,但问题是我不知道在索引太长的情况下它会返回什么。 例如 operator[] 重载是这样的:

    char& operator[] (int i)
    {
        try
        {
            if(i<0 || i>=length)
                throw indexException();
            return field[i];
        }
        catch(indexException& e)
        {
            std::cerr << e.what() << std::endl;
        }
    }

这是个例外:

class indexException:std::exception
{
    public:
    virtual const char* what()
    {
        return "Index is either too long, or negative";
    }
};

它必须返回一个 char 引用,而不仅仅是一个 char,因为我想让它可赋值,例如,如果我有一个字符串 str,我可以说 str[5]='c'。 我也想处理异常,而不是用 exit() 退出程序。 因此,如果出现异常,它不返回任何值,则字符串也可能为空。 我应该返回什么?我会让它类似于 std::string 但我不太了解 std::string 是如何实现的。

【问题讨论】:

  • 你为什么在operator[] 中捕获异常?让它逃给用户,让他们抓住它;在同一个地方扔和接是没有用的。

标签: c++ stl exception-handling stdstring


【解决方案1】:

如果您要在同一个块中捕获异常,那么抛出异常没有多大意义。如果您希望返回某些内容而不是在函数之外抛出错误,只需让您的 if 语句控制事物即可。

标准字符串类不会对其索引进行任何检查,因此不会增加额外开销。如果索引超出范围,则会出现未定义的行为,因为您在内部缓冲区上使用了超出范围的索引。

您可以选择要返回的越界索引。零是一个不错的选择,因为这表示 C 样式字符串的结束。

【讨论】:

  • 我可以返回零,但它返回一个引用。那么我该怎么办,分配一个新的字符并将其设置为零?
  • 如果需要边界检查,直接抛出异常即可。
  • @Ramy :返回一个哨兵char&amp;(而不是char const&amp;)实际上并不可行。 IMO 你最好走 UB 或异常路线。
  • @RamyAlZuhouri:选项是检查,在这种情况下你需要报告错误(这是at方法,错误被报告为异常)或根本不检查,在这种情况下,您将忽略边界,并返回对元素所在位置的引用(如果字符串足够长),这是未定义的行为。但这已经记录在您的界面中:使用越界索引调用 operator[] 是未定义的行为,因此您可以安全地责怪调用者。
  • @RamyAlZuhouri,我对此完全置之不理——当然,您不能返回对文字零的引用。您可以在返回之前将其设置为零的类的 char 成员。或者您可以只返回字符串的第一个或最后一个字符。这完全取决于你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-15
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 2016-01-26
  • 1970-01-01
  • 2016-03-15
相关资源
最近更新 更多