实现 C++字符串运算符

发布于 2024-12-19 17:13:50 字数 1204 浏览 0 评论 0原文

我有一个关于 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;
}

I have a problem about char*, string add together
such like this:

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

and I have three operator below

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

but I use 1 and 3 it will crash, but I use 1 and 3 can do good.

My problem is the order isn't that s3 + "," first so use operator w first
and the result use operator 3, but the fact isn't as my thought.

Can anyone explain why this happens?

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

这个俗人 2024-12-26 17:13:50

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

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

然后再进行链接:

s2 = s3 + ","  + s1;

这样您就可以更清楚地判断问题所在。

Try testing simpler things first:

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

before moving on to chaining:

s2 = s3 + ","  + s1;

that way you can tell what the issue is more clearly.

柠檬色的秋千 2024-12-26 17:13:50

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 ];

In

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

you should write:

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

And here:

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

you should write:

  tmp.str_ = new char [ strlen(ch) + strlen(mystr.str_) + 1 ];
毁梦 2024-12-26 17:13:50

你读过这篇文章吗? 什么是三法则?

基于您手动管理内存的方式这些功能,我认为可以肯定地假设您没有。不管怎样,一旦你正确地实施了三巨头,这就是你应该做的。首先你应该有两个完整的成员。一种用于存储字符串的大小,另一种用于存储动态数组的容量。然后,您需要一个私有函数,我们将其称为 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,但也许您正在尝试了解手动内存管理,这很好。

现在,您应该实现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 * 的隐式转换,那么它应该涵盖所有这些。但是,如果您编写了采用 const char * 的额外 operator+= 来减少分配次数,那么您可能还应该编写采用 const char * 的操作符+= 在它的右侧。看起来和上面的一样,只是第二个参数的类型改变了。您不需要为反向操作编写一个,因为无论如何 lhs 都需要分配为 Mystring。

Have you read this? What is The Rule of Three?

Based on the way you manually manage memory in these functions, I think it's safe to assume that you haven't. Anyway, once you do properly implement the big three, here is what you should do. First you should have two integral members. One to store the size of the string, and one to store the capacity of the dynamic array. Then you want to have a private function, let's call it increase_capacity, that increases the capacity if necessary. All your memory allocation will take place there, in one spot. It will simplify things greatly. It might look something like this:

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;
}

Now, you should also have a resize function, that adjusts the size, if necessary.

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.
}

Better than all that above, you should just use vector<char>, but maybe you're trying to understand manual memory management, that's fine.

Now, you should implement operator+=, as a member:

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

If you want, you can also implement one that takes const char *, that will save an allocation that would happen if you relied on the implicit conversion.

Finally, you can implement your operator+:

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

If you have an implicit conversion from const char *, that should cover all of them. But if you wrote the extra operator+= that takes a const char * in order to do fewer allocations, you should probably also write the one that takes const char * on it's right side. It looks the same as the one above, just the type of the second parameter changes. You shouldn't need to write one for the reverse operation, since the lhs will need to be allocated as a Mystring anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文