所以我有一个基本代码:尝试使用两个函数定义字符串数据类型,连接并打印它。
所以我所做的是声明一个 .cpp 文件和一个包含类内容的 .h 文件,并编写一个 main.cpp 来尝试测试我的代码,但我遇到了意外错误。首先,这是我的 main.cpp、stringConcat.h 和 stringConcat.cpp 文件 -
main.cpp:
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include "stringConcat.h"
using std::cin;
using std::cout;
using std::endl;
using std::initializer_list;
using std::string;
using std::vector;
int main()
{
char input1[101], input2[101];
cin.getline(input1, 101);
cin.getline(input2, 101);
String str1(input1);
String str2(input2);
String result = str1 + str2;
result.display();
return 0;
}
stringConcat.h:
class String
{
public:
char *a;
int length;
String(char b[], int size=101)
{
a = &b[0];
length = size;
}
String operator+(const String &other);
void display();
};
stringConcat.cpp:
#include <iostream>
#include "stringConcat.h"
using namespace std;
String String::operator+(const String &other)
{
int total = length + other.length;
char temp[total];
int counter = 0;
for(int i = 0; i < length; i++)
{
if(*(a+i) == '\0')
break;
temp[counter++] = *(a+i);
}
temp[counter++] = ' ';
for(int i = 0; i < other.length; i++)
{
if(*(other.a+i) == '\0')
break;
temp[counter++] = *(other.a+i);
}
temp[counter++] = '\0';
return String(temp, counter);
}
void String::display()
{
for(int i = 0; i < length; i++)
{
if(*(a+i) == '\0')
break;
cout<<*(a+i);
}
cout<<endl;
}
所以我想做的是用一个指向 char 数组的第一个元素的 char 指针初始化一个字符串,最大长度为 100(并且 成为第 101 个字符),然后通过重载 + 运算符来连接两个字符串。一切都运行正常,我通过运行示例测试用例(例如 input1 =“YX”,input2 =“GH”)检查了代码,并且得到结果 =“YX GH”,但控制台上打印的内容是 Y(仅是第一个字符)字符串)。
我用我的代码测试的一些东西:
如果我在代码中的其他任何地方(例如在构造函数中)使用显示函数中的循环(以显示字符串的每个字符),我会得到正确的输出,但不知何故它在显示函数中失败。发生这种情况是因为 cout 仅在第一次调用时才工作(出于某种原因我不明白)。就像我添加语句 cout<<"Hello"<
我什至尝试刷新cout,它没有改变任何东西,但我知道会发生这种情况,因为for循环结束后的endl应该刷新它本身。
因此,正如 Botje 在他的评论中所述,我在operator+函数中定义了一个局部变量temp,并将数组传递给String构造函数(通过引用传递),因此在operator+完成后,没有人可以停止内容下一个内存位置被更改,并且我最初使用的编译器不允许我访问我无法访问的内存位置(因为它是一个在线编译器,它释放了下一个内存位置)。
我检查了我电脑上的本地编译器,它像以前一样打印了第一个字母和一些随机字符。就像前面提到的 YX 和 GH 的例子一样,输出是 Y?1a 还是 Y3p?或 Y 之后的一些随机内容。
因此,我在operator+函数外部定义了临时数组,当我再次运行代码时,我得到了所需的输出,确认错误是由于本地数组和数组的引用属性传递造成的。
这是我编辑的 stringConcat.cpp 和 stringConcat.h 文件:
stringConcat.h:
class String
{
public:
char *a;
int length;
char temp[202];
String(char b[], int size=101)
{
a = &b[0];
length = size;
}
String operator+(const String &other);
void display();
};
stringConcat.cpp:
#include <iostream>
#include "stringConcat.h"
using namespace std;
String String::operator+(const String &other)
{
int counter = 0;
for(int i = 0; i < length; i++)
{
if(*(a+i) == '\0')
break;
temp[counter++] = *(a+i);
}
temp[counter++] = ' ';
for(int i = 0; i < other.length; i++)
{
if(*(other.a+i) == '\0')
break;
temp[counter++] = *(other.a+i);
}
temp[counter++] = '\0';
return String(temp, counter);
}
void String::display()
{
for(int i = 0; i < length; i++)
{
if(*(a+i) == '\0')
break;
cout<<*(a+i);
}
cout<<endl;
}
但是,正如 Bortje 所说,现在我们对于由operator+函数创建的所有字符串都有相同的内存位置。就像如果我们有另一个字符串 str3 并且我们执行 String result_new = str1 + str3 一样,我们会覆盖字符串结果(由 str1 + str2 形成),因为 char temp[202] 是相同的 - 对象 str1 的属性两种情况。
所以我更改了 stringConcat.cpp 和 stringConcat.h 文件以获得最终文件:
stringConcat.h:
class String
{
public:
char *a;
int length;
String(char b[], int size=101)
{
a = &b[0];
length = size;
}
String operator+(const String &other);
void display();
};
stringConcat.cpp:
#include <iostream>
#include "stringConcat.h"
using namespace std;
String String::operator+(const String &other)
{
int counter = 0;
int total = length + other.length;
char *temp = new char[total];
for(int i = 0; i < length; i++)
{
if(*(a+i) == '\0')
break;
temp[counter++] = *(a+i);
}
temp[counter++] = ' ';
for(int i = 0; i < other.length; i++)
{
if(*(other.a+i) == '\0')
break;
temp[counter++] = *(other.a+i);
}
temp[counter++] = '\0';
return String(temp, counter);
}
void String::display()
{
for(int i = 0; i < length; i++)
{
if(*(a+i) == '\0')
break;
cout<<*(a+i);
}
cout<<endl;
}