将运算符重写应用于具有动态分配指针的类

Apply operator overriding to classes with dynamic allocation pointers

本文关键字:动态分配 指针 运算符 重写 应用于      更新时间:2023-10-16

我已经定义了MyString类,现在我想实现加法操作。发生内存泄漏很可怕,所以我负责从析构函数中释放动态分配的指针。

#include <iostream>
class MyString {
private:
    int _size;
    char* _str;
public:
    MyString() {
        _size = 0;
        _str = nullptr;
    }
    MyString(int size, char* str) {
        _size = size;
        _str = new char[size + 1];
        strcpy(_str, str);
    }
    ~MyString() {
        delete[] _str;
    }
    void print() {
        std::cout << _str << std::endl;
    }
    friend MyString operator+(const MyString& lhs, const MyString& rhs);
};
MyString operator+(const MyString& lhs, const MyString& rhs) {
    char* temp = new char[lhs._size + rhs._size + 1];
    strcpy(temp, lhs._str);
    strcat(temp, rhs._str);
    MyString ret(lhs._size + rhs._size, temp);
    delete[] temp;
    return ret;
}
int main() {
    MyString first(5, "first");
    MyString second(6, "second");
    MyString add = first + second;
    first.print();
    second.print();
    add.print();
}

但是,如果我编译代码并运行它,first.print()second.print()打印得很好,但add.print()会打印垃圾值,并崩溃(调试断言失败!

输出:

first
second
硼硼硼硼硼硼硼硼?흚 (and creashes :(.. )

如果我注释并运行析构函数,它打印得很好,但会发生内存泄漏。为什么会这样?我已经查看了几个运算符覆盖的示例,但我还没有找到这种指针动态分配的示例。

任何建议将不胜感激!

MyString operator+(const MyString& lhs, const MyString& rhs) {
    char* temp = new char[lhs._size + rhs._size + 1];
    strcpy(temp, lhs._str);
    strcat(temp, rhs._str);
    MyString ret(lhs._size + rhs._size, temp);
    delete[] temp;
    return ret;
}

在此函数结束时,"ret"被销毁,它调用析构函数并删除缓冲区。返回的是从"ret"复制的MyString的新实例,其缓冲区指向与原始内存相同的内存位置。由于它已被删除,您现在正在打印垃圾。

要解决此问题,您可以添加一个复制构造函数以确保复制缓冲区:

class MyString {
// Other class details
public:
    MyString(const MyString & other) : MyString(other._size, other._str) {}
// Other class details
}

这将确保在一个 MyString 分配给另一个 MyString 时复制缓冲区。

#include<iostream>
using namespace std;
class Mystring{
private:
    int size;
    char *str;
public:
    friend Mystring operator*(const Mystring &a, const int &d);
    friend Mystring operator+(const Mystring &a, const Mystring& b);
    friend ostream& operator << (ostream &os, const Mystring a);
    friend istream& operator >> (istream &is, const Mystring a);

Mystring (int a, char b) {
    this->size = a;
    this->str = new char(a);
    for (int i = 0; i < a; i++) {
        this->str[i] = b;
    }
}
~Mystring() {}
};
Mystring operator+(const Mystring &a, const Mystring& b) {
Mystring  c(a.size + b.size, { 0 });
for (int i = 0; i < a.size; i++)
{
    c.str[i] = a.str[i];
}
for (int i = 0; i < b.size; i++)
{
    c.str[a.size + i] = b.str[i];
}
return c;
}
Mystring operator*(const Mystring& a,const int &d){
int z = a.size*d;
Mystring c(z, { 0 });
int k=0;
for (int j = 0; j < d; j++)
{
    for (int i = 0; i < a.size; i++)
    {
        c.str[k+i] = a.str[i];
    }
    k = a.size + k;
}
return c;
}
ostream& operator << (ostream &os, const Mystring a) {
os << "[";
int i;
for ( i = 0; i < a.size; i++)
{
    os << a.str[i];
}
os << "]";
return os;
}
istream& operator >> (istream &is, const Mystring a) {
for (int i = 0; i < a.size; i++)
{
    cout << i << "번째 문자 : ";
    is >> a.str[i];
}
return is ;
}

int main()
{
int aSize, bSize, iter;
char aInit, bInit;
cout << "문자열A의 크기와 초기문자를 입력: ";
cin >> aSize >> aInit;
Mystring str1(aSize, aInit);
cout << str1 << endl;
cout << "문자열A 입력" << endl;
cin >> str1;
cout << str1 << endl;
cout << "문자열B의 크기와 초기문자를 입력: ";
cin >> bSize >> bInit;
Mystring str2(bSize, bInit);
cout << str2 << endl;
cout << "문자열B 입력" << endl;
cin >> str2;
cout << str2 << endl;
cout << "문자열A와 문자열B 합치기 : ";
Mystring str3 = str1 + str2;
cout << str3 << endl;
cout << "문자열A 반복횟수 입력 : ";
cin >> iter;
Mystring str4 = str1*iter;
cout << str4 << endl;

}

enter code here

为什么错误~Mystring(({}