C ++中的字符串类赋值运算符重载

用户83962

我定义了自己的字符串类MyString。一切正常,直到我由重载的operator =将一个对象分配给另一个对象。我知道问题出在哪里,但我不知道如何解决。有帮助吗?

class MyString{
public:
    MyString( const MyString *strIni );
    MyString( const char *str);
    ~MyString();
    MyString& operator=( const MyString &str );
private:
    char *str;
}


MyString::MyString( const MyString *strIni ){
    this->str = new char[strlen(strIni->str)+1];
    strcpy(this->str,strIni->str) ;
};


MyString::MyString( const char *str){
    this->str = new char[ strlen(str) + 1 ];
    strcpy(this->str , str);
};

MyString::~MyString(){
    delete [] this->str ;
    cout << "successfully deleted..." << endl;
};


MyString& MyString::operator=( const MyString &str ){
    // temp obj holding the rhs
    MyString strTmp(str);
    // temp char pointer holding the rhs
    char *cTmp = strTmp.str;
    // temp obj holding this, later release this memory 
    strTmp.str = this->str ;
    // this holding rhs; assignment done.
    this->str = cTmp;
    return *this ;
};


int main(){
    {                                  // line 1
        MyString mystr1("string #1");  // line 2
        MyString mystr2("string #2");  // line 3
        mystr1 = mystr2;               // line 4
    }                                  // line 5
    return 0;
}

代码的问题是:在第4行,在赋值后,两个对象mystr1和mystr2中的指针都指向相同的字符串“字符串#2”。当程序从第5行的括号中跳出时,析构函数将按以下顺序自动调用:mystr2,然后是mystr1。销毁mystr2之后,将释放“字符串#2”的内存。当mystr1的析构函数试图释放不存在的内存时,程序崩溃了。

任何人都可以帮助我修复重载成员函数。当我分配mystr1 = mystr2时,我可以创建一个新的字符串,而不是使两个指针指向同一字符串。

非常感谢!!



有更多问题的更新……谢谢吨!!

实际上,我在重载功能中使用了复制和交换功能。基于@MateuszKołodziejski的建议,我对其进行了修改:

MyString& MyString::operator=( const MyString &rhs ){
    if( this != &rhs ){
        // copy using constructor
        MyString strTmp(rhs) ;
        // swap        
        char *cTmp = strTmp.str;
        // strTmp will be destructed, thus the memory in this will be released
        strTmp.str = this->str ;
        // size of rhs
        const int str_size = strlen(rhs.str);
        this->str = new char[str_size+1];
        copy(rhs.str,rhs.str+str_size,this->str);
    }
    return *this ;
};

调用析构函数时,不会崩溃。但是,如果添加了打印输出成员函数,则似乎还有另一个问题:

void MyString::printout(){
    int str_size = strlen(this->str);
    cout << "string size: " << str_size << endl ;
    for( int i=0;i<str_size;i++ ){
        cout << *(this->str + i);
    }
}

在主要功能上:

int main(){
    {                                  
        MyString mystr1("string #1");  
        MyString mystr2("string #2");  
        mystr1.printout();
        mystr2.printout();
        mystr1 = mystr2;  
        cout << "after assignment: " << endl;
        mystr1.printout();
        mystr2.printout();             
    }                                  
return 0;
}

结果是:

string #1
string #2
after assignment...
string #2═²²²²
string #2

似乎mystr1不正常...

有人可以帮我解释一下吗?

谢谢吨!

马特乌斯·科沃兹(MateuszKołodziejski)

您显然必须修复operator =()实现。

#include <algorithm>

MyString& MyString::operator=( const MyString &rhs ) // (1)
{
    if (this != &rhs) // (2)
    {
        delete[] this->str; // (3)
        this->str = NULL;

        const int str_length = strlen(rhs.str);

        this->str = new char[str_length + 1];
        this->str[str_length] = '\0';
        std::copy(rhs.str, rhs.str + str_length, this->str); // (4)
    }

    return *this;
}

1)为变量名使用“ rhs”(右侧)而不是“ str”,以避免歧义。

2)始终检查您的对象是否未分配给自己。

3)在分配新的内存之前,释放旧的已分配内存。

4)将rhs的内容复制到this-> str,而不仅仅是重定向指针。

编辑:

添加了this-> str = NULL; 避免在新的对象和以后的对象解构中重复删除可能出现的异常。

这是一个幼稚的实现-您必须知道new会引发异常。副本交换成语会更好,这里由@nyarlathotep建议,并说明如下:复制和交换

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++运算符重载,我自己的字符串类

来自分类Dev

尝试重载模板类中的/运算符的C ++错误

来自分类Dev

如何在C ++中重载赋值运算符

来自分类Dev

C ++:赋值运算符后的++运算符重载

来自分类Dev

C ++-重载的赋值运算符内存泄漏

来自分类Dev

C ++-具有派生类的“安全/标准”方法“继承”基类中的重载赋值运算符

来自分类Dev

检测重载C ++运算符中的自赋值

来自分类Dev

C中的赋值运算符重载

来自分类Dev

C ++赋值运算符和重载

来自分类Dev

C ++矩阵类:重载赋值运算符

来自分类Dev

C ++中的矩阵类输入运算符重载>>

来自分类Dev

使用模板类在C ++中重载运算符

来自分类Dev

<< C ++中用于字符串的运算符与重载+运算符

来自分类Dev

C ++赋值运算符=派生类的重载

来自分类Dev

在C ++中重载复合赋值运算符

来自分类Dev

C ++中字符串的加号运算符

来自分类Dev

类中C ++运算符重载的语法

来自分类Dev

C ++类中无法重载+运算符

来自分类Dev

重载C ++中字符数组的赋值运算符

来自分类Dev

C ++模板类中的错误重载()运算符

来自分类Dev

C ++复制赋值运算符类

来自分类Dev

C ++重载另一个类的赋值运算符

来自分类Dev

如何在C ++中重载赋值运算符

来自分类Dev

C ++运算符重载模板类

来自分类Dev

模板类中的C ++重载运算符

来自分类Dev

使用模板类在C ++中重载运算符

来自分类Dev

C ++赋值运算符中的矩阵类

来自分类Dev

具有非类型参数的 C++ 模板类:如何重载赋值运算符?

来自分类Dev

C 中的字符串与运算符的比较