任何人都可以帮助我。下面是我正在尝试执行的代码。没有编译时错误,但是当控件转到字符串复制语句时程序崩溃。我试图修复它差不多一个小时,但仍然没有成功。
#include <iostream>
using namespace std;
class test
{
private:
char* name;
friend istream& operator >>(istream&, test&);
};
istream& operator >> (istream& is, test& t)
{
char c[20];
cout << "enter something";
is >> c;
strcpy(t.name, c);
return is;
}
int main()
{
test obj;
cin >> obj;
}
答案 0 :(得分:7)
name
指针在您调用strcpy
时未初始化,这会为您的程序提供未定义的行为。
要避免此类问题,请使用std::string
而不是C字符串。更具体地说,用这种方式重新定义你的课程:
#include <string> // Needed for std::string
class test
{
private:
std::string name;
friend istream& operator >>(istream&, test&);
};
要使程序编译,您可以通过这种方式调整operator >>
的重载:
istream& operator >> (istream& is, test& t)
{
cout << "enter something";
is >> t.name;
return is;
}
但请注意,您不应该提示用户提取 in 提取运算符(即在operator >>
的重载内)。插入运算符只应从输入流中提取类型为test
的对象。
因此,提供一个完整的例子:
#include <iostream>
#include <string>
class test
{
private:
std::string name;
friend std::istream& operator >>(std::istream&, test&);
};
std::istream& operator >> (std::istream& is, test& t)
{
is >> t.name;
return is;
}
int main()
{
test obj;
std::cout << "enter something: ";
std::cin >> obj;
}
还要避免using
指令,例如:
using namespace std;
特别是在命名空间范围内,特别是在标题中(不是你的情况,但仍然) - 它们往往会导致与std
命名空间中存在的实体发生名称冲突。
修改强>
由于您似乎不允许使用std::string
,因此只有原始答案的第一句仍然有效 - 以及关于您应该向用户询问输入的部分,也许。
这就是您可以编写的用于分配用户输入的字符串的t.name
副本的内容:
t.name = strdup(c);
您需要为<cstring>
添加strdup()
标准标头:
#include <cstring>
我还建议在name
类的构造函数中将test
指针初始化为null - 它不会被隐式生成的默认构造函数初始化:
class test
{
test() : name(nullptr) { } // Use NULL instead of nullptr in C++03
private:
char* name;
friend istream& operator >> (istream&, test&);
};
所以在一个完整的程序中:
#include <iostream>
#include <cstring>
class test
{
public:
test() : name(nullptr) { }
private:
char* name;
friend std::istream& operator >>(std::istream&, test&);
};
std::istream& operator >> (std::istream& is, test& t)
{
char c[20];
is >> c;
t.name = strdup(c);
return is;
}
int main()
{
test obj;
std::cout << "enter something: ";
std::cin >> obj;
}