【发布时间】:2015-10-29 14:28:11
【问题描述】:
我正在为家庭作业定义自己的字符串类。我注意到以下代码
class MyString {
public:
MyString(const char* s = NULL) {len = strlen(s); str = new char[len + 1]; strcpy(str, s);}
~MyString() {delete [] str;}
friend ostream& operator << (ostream& ost, const MyString& s) { ost << s.str; return ost;}
friend MyString operator + (const MyString &s1, const MyString &s2) {
int length = strlen(s1.str) + strlen(s2.str);
char *str = new char[length + 1];
strcpy(str, s1.str);
strcat(str, s2.str);
return MyString(str);
}
private:
char * str;
int len;
};
int main () {
MyString s1 = MyString("hello");
MyString s2 = MyString("world");
cout << s1 + s2 << endl;
return 0;
}
有效,因为返回对象是在最后一刻创建的。但是下面的代码
class MyString {
public:
MyString(const char* s = NULL) {len = strlen(s); str = new char[len + 1]; strcpy(str, s);}
~MyString() {delete [] str;}
friend ostream& operator << (ostream& ost, const MyString& s) { ost << s.str; return ost;}
friend MyString operator + (const MyString &s1, const MyString &s2) {
int length = strlen(s1.str) + strlen(s2.str);
MyString temp;
temp.str = new char[length + 1];
strcpy(temp.str, s1.str);
strcat(temp.str, s2.str);
return temp;
}
private:
char * str;
int len;
};
int main () {
MyString s1 = MyString("hello");
MyString s2 = MyString("world");
cout << s1 + s2 << endl;
return 0;
}
没有,给我一个运行时错误。所以我很困惑为什么第二种方法会失败,如果在重载的运算符中定义、修改和返回临时对象。
【问题讨论】:
-
我强烈推荐两件事:(1)不要使用手动内存管理;相反,环绕
std::unique_ptr<char[]>。 (2) 不要使用 C 字符串函数。改用 C++ 标准库算法(特别是,这里应该是std::copy。 -
MyString temp;使用带有s == nullptr的构造函数,那么strlen(s)是UB。 -
当心:你目前违反了三法则。