C++ c+中的字符串类赋值运算符重载+;
我定义了自己的字符串类MyString。在我通过重载运算符=,将一个对象分配给另一个对象之前,一切都很正常。我知道问题在哪里,但不知道如何解决。有什么帮助吗C++ c+中的字符串类赋值运算符重载+;,c++,string,overloading,destructor,operator-keyword,C++,String,Overloading,Destructor,Operator Keyword,我定义了自己的字符串类MyString。在我通过重载运算符=,将一个对象分配给另一个对象之前,一切都很正常。我知道问题在哪里,但不知道如何解决。有什么帮助吗 class MyString{ public: MyString( const MyString *strIni ); MyString( const char *str); ~MyString(); MyString& operator=( const MyString &str ); pr
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;
}
调用析构函数时,不会发生崩溃。但如果添加了打印输出成员函数,则会出现另一个问题:
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);
}
}
看来mystr1是不正常的
有人能为我解释一下吗
谢谢你 这里的问题是声明
MyString strTmp(str);
在赋值运算符中,调用默认的隐式生成的复制构造函数。该构造函数将只复制指针,而不是创建新指针并复制字符串的内容
使用
MyString
指针的构造函数不是复制构造函数,复制构造函数将使用常量引用。如果您将使用指向MyString的指针的构造函数改为使用引用,那么它会工作得更好。您显然必须修复运算符=()实现
#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;
}
#include.我当然希望这是学校作业或类似作业的可能副本,因为std::string
已经足够好了。使用MyString&MyString::operator=(const MyString&rhs){
相反。太多的str
表示不同的东西。也许问题会更清楚。不要重新设计控制盘?这种错误就是为什么你应该使用现有的、有良好文档记录的和经过测试的类。在这种情况下,std::string
。你可能需要调查strdup
来复制assi中的字符串gnment操作符。@nyarlathotep是的,我刚刚意识到,这就是问题所在,我为它添加了一个答案。即使OP确实创建了一个深度复制复制构造函数,赋值操作符仍然会使用temp对象中的char*
,该对象随后被删除,对吗?@nyarlathotep否,OP交换指针,所以它是旧的this->str
被删除。啊,是的,错过了-可能是std::swap
,以提高可读性;)只需注意:您的代码不提供“强”异常安全性:如果新字符抛出异常,this->str
仍然指向未分配的空间(之前删除的内存).这就是为什么这里更倾向于使用swap成语的原因。仔细想想,它甚至没有提供基本的异常安全性,因为每当MyString被销毁时,str
会再次被删除…@nyarlathotep True,这只是一种天真 实现。复制交换习惯用法会更好。@nyarlathotep已编辑。谢谢您的评论。这是一个面试问题,不是作业。我实际上在使用运算符重载函数中的复制和交换。
string #1
string #2
after assignment...
string #2═²²²²
string #2
MyString strTmp(str);
#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;
}