在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;
}
但是请注意,您不应该在提取操作符内(即在 的重载内)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
在类的构造函数中将指针初始化为 null test
- 它不会被隐式生成的默认构造函数初始化:
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;
}