实现string的C ++运算符

时间:2011-12-05 14:19:40

标签: c++ operator-keyword

我有关于char *的问题,字符串加在一起 像这样:

enter code here
s2 = s3 + "," + s1; 

我在

下面有三个操作员
friend Mystring operator+( const Mystring &lhs, const Mystring &rhs);  -- 1
friend Mystring operator+( const Mystring &mystr, const char *ch ); -- 2
friend Mystring operator+( const char *ch, const Mystring &mystr ); -- 3

但我使用1和3会崩溃,但我使用1和3可以做得很好。

我的问题是顺序不是s3 +“,”首先使用运算符w 结果使用运算符3,但事实并非如我所想。

有人可以解释为什么会这样吗?

Mystring operator+( const Mystring &mystr,const char *ch )
{
  Mystring tmp;
  tmp.str_ = new char[ strlen(mystr.str_)+2 ];
  strcpy( tmp.str_, mystr.str_ );
  strcat( tmp.str_, ch );
  return tmp;
}


Mystring operator+( const char *ch, const Mystring &mystr )
{
  Mystring tmp;
  tmp.str_ = new char[ strlen(mystr.str_)+strlen(mystr.str_)+1 ];
  strcpy( tmp.str_, mystr.str_ );
  strcat( tmp.str_, mystr.str_ );
  return tmp;
}

Mystring operator+( const Mystring &lhs, const Mystring &rhs )
{
  Mystring tmp;
  tmp.str_ = new char[ strlen(lhs.str_)+strlen(rhs.str_)+1 ];
  strcpy( tmp.str_, lhs.str_ );
  strcat( tmp.str_, rhs.str_ );
  return tmp;
}

3 个答案:

答案 0 :(得分:2)

首先尝试测试更简单的事情:

s2 = s3 + ",";
s2 = "," + s3;
s3 = s1 + s2;

继续进行链接之前:

s2 = s3 + ","  + s1;
通过这种方式,您可以更清楚地了解问题所在。

答案 1 :(得分:1)

Mystring operator+( const Mystring &mystr,const char *ch )
{
  Mystring tmp;
  tmp.str_ = new char[ strlen(mystr.str_)+2 ];

你应该写:

  tmp.str_ = new char[ strlen(mystr.str_) + strlen(ch) + 1 ];

在这里:

Mystring operator+( const char *ch, const Mystring &mystr )
{
  Mystring tmp;
  tmp.str_ = new char[ strlen(mystr.str_)+strlen(mystr.str_)+1 ];

你应该写:

  tmp.str_ = new char [ strlen(ch) + strlen(mystr.str_) + 1 ];

答案 2 :(得分:0)

你读过这个吗? What is The Rule of Three?

根据您在这些功能中手动管理内存的方式,我认为可以安全地假设您没有。无论如何,一旦你正确实施了三巨头,这就是你应该做的。首先,你应该有两个完整的成员。一个用于存储字符串的大小,另一个用于存储动态数组的容量。然后你想拥有一个私有函数,我们称之为increase_capacity,如果需要的话增加容量 。所有内存分配都将在那里进行。它会大大简化事情。它可能看起来像这样:

void increase_capacity(int cap)
{
    if (cap <= capacity_) return;
    char * temp = new char[cap];
    capacity_ = cap;
    memcpy(temp, str_, size_); // Or size_ + 1 if your string is null terminated.
                               // It doesn't have to be.
    delete [] str_;
    str_ = temp;
}

现在,您还应该有一个调整大小的功能,如果需要,可以调整大小。

void resize(int size)
{
    if (size > capacity_)
    {
        int cap = capacity_ * 2;
        cap = cap > size ? cap : size;
        increase_capacity(cap);
    }

    size_ = size;
    // Fill in new elements with some default value, or don't.
}

比上述所有内容更好,你应该只使用vector<char>,但也许你正在尝试理解手动内存管理,这很好。

现在,您应该将operator + =实现为成员:

Mystring & operator+=(const Mystring & rhs)
{
    int old_size = size_;
    resize(size_ + rhs.size_);
    memcpy(str_ + old_size, rhs.str_, rhs.size_);
    return *this;
}

如果你愿意,你也可以实现一个const char *,这将节省你依赖隐式转换时会发生的分配。

最后,您可以实施operator+

Mystring operator+(Mystring lhs, const Mystring & rhs)
{
    return lhs += rhs;
}

如果您从const char *进行隐式转换,则应涵盖所有这些转化。但是如果你写了额外的operator+=,它需要一个const char *来做更少的分配,你应该也可以写一个const char *就可以了。它看起来与上面的相同,只是第二个参数的类型发生了变化。您不需要为反向操作编写一个,因为无论如何都需要将lhs分配为Mystring。