关于我的程序输出唯一不正确的是,有一个'!' '钓鱼'之后。我试过调试它,但从来没有'!'在记忆中。
以下是此行的输出
One more: gone down to the fishing! hole
这是s6和s7的创建
MyString s6("gone ");
MyString s7("fishing");
以下是生成语句
的行cout << "One more: " << s6 + "down to the " + s7 + " hole" << endl << endl;
这是&lt;&lt;操作员过载功能
ostream& operator<<(ostream& leftOp, const MyString& rightOp)
{
leftOp << rightOp.stringArray;
return leftOp;
}
这是+运算符重载函数
MyString MyString::operator+(const char* rightOp) const
{
MyString result; // new object used to store result
result.stringSize = stringSize + strlen(rightOp);
// if the string does not fit in the array
if( result.stringSize > result.stringCap )
{
delete[] result.stringArray;
result.stringCap = ( stringSize + 15 ) & ~15;
result.stringArray = new char[stringCap + 1];
}
strcpy(result.stringArray, stringArray);
strcat(result.stringArray, rightOp);
return result;
}
s7在程序中的任何其他位置都没有被调用,所以我不认为还有其他代码需要显示。任何帮助将不胜感激。
答案 0 :(得分:3)
很难判断您的代码是否存在问题 我会看看其他成员。 你是否遵守了3 的规则?
我会指出你违反了一项基本的OO规则。
除非very
有充分的理由,否则你不应该操纵另一个对象的成员。
在这里你的对象是摆弄结果。
如果您将代码编写为:
,代码会更清晰MyString MyString::operator+(const char* rightOp) const
{
MyString result(*this); // make a copy of this.
result += rightOp; // Let result fiddle with its own members here.
return result;
}
基于以下评论。
基本上:如果你的对象拥有动态分配的内存(即它调用new / delete),那么编译器生成的方法的默认版本不能按你的意愿工作;你应该定义自己的版本:
基本上:
* Copy Constructor
* Assignment Operator
* Destructor
* Not part of rule of 3, but you probably also need a normal constructor.
简单的事情是你可能已经有了析构函数(否则就不会有损坏),并且可以根据复制构造函数编写赋值运算符。所以你需要做的就是编写一个正确版本的拷贝构造函数,一切都应该有效。
/*
* Assignment operator using Copy and swap Idiom.
* Copy uses copy constructor (here done in pass by value)
*
* You then just swap the current content with the copy
*/
MyString& MyString::operator=(MyString rhs)
{
(*this).swap(rhs);
return *this;
}
答案 1 :(得分:1)
如果你将stringCap分配给你的数组,你介意'\ 0'吗?存储字符串的char *必须是大小为size-of-string + 1
问题可能是你连续两个MyString。第二个字符串fishing可能有一个太大的stringSize值。
而不是result.stringCap = ( stringSize + 15 ) & ~15;
为什么不简单地写:
result.stringCap = result.stringSize + 1;
答案 2 :(得分:0)
您没有在正常情况下分配stringArray
,并且您没有在过大的情况下重置stringSize,并且strncpy更安全:
MyString MyString::operator+(const char* rightOp) const
{
MyString result; // new object used to store result
result.stringSize = stringSize + strlen(rightOp);
// if the string does not fit in the array
if( result.stringSize > result.stringCap )
{
delete[] result.stringArray;
result.stringCap = ( stringSize + 15 ) & ~15;
// don't allocate here
result.stringSize = stringCap;
}
// always allocate for the new string
result.stringArray = new char[result.stringSize + 1];
strncpy(result.stringArray, stringArray, result.stringSize);
strncat(result.stringArray, rightOp, strlen(rightOp) + 1);
return result;
}
编辑:好的,不要理会。我假设有关MyString类的某些事情,显然并非如此。所以,这就是我现在可以指出的:
if( result.stringSize > result.stringCap )
{
delete[] result.stringArray;
result.stringCap = ( stringSize + 15 ) & ~15;
result.stringArray = new char[stringCap + 1]; // WRONG stringCap!
result.stringArray = new char[result.stringCap + 1]; // right stringCap
}
你可以尝试简化问题,缩小问题范围:
cout << "One more: " << s6 + "down to the " << s7 + " hole" << endl << endl;
问题可能在operator+(const MyString&)
而不是operator+(const char*)
?
答案 3 :(得分:0)
if( result.stringSize > result.stringCap )
应为if( result.stringSize >= result.stringCap )
以允许空终止。您还需要重置result.stringSize
。